I want to write class for Enums in Python.
My issue is that I want to have same value for different enum inputs. For example:
class Animal(Enum):
Cat = ['Perian cat', 'Bengal cat', 'Siamese cat']
So then I could use it like this:
some_animal = Animal('Persian cat')
print(some_animal)
>> Animal.Cat
I think it is not possible, but just to be sure I wanted to ask for that here.
UPDATE
I tried this solution:
class _Cat(Enum):
BENGAL = 'Bengal cat'
PERSIAN = 'Persian cat'
SIAMESE = 'Siamese cat'
class Animal(Enum):
Cat = _Cat
It works in that sense that I can access the values of the Cat class, but what I would like to achieve is something like this:
some_animal = Animal('Persian cat')
print(some_animal)
>> Animal.Cat.PERSIAN
Thanks.
CodePudding user response:
You can obtain a close result with the functional API. In fact the hard part in not to have multiple members with same value, but to have names which contain spaces (ie: cannot be identifiers):
Animal = Enum('Animal', (('Persian cat', 'cat'), ('Bengal cat', 'cat'),
('Siamese cat', 'cat')))
Then you can do:
>>> print(Animal['Persian cat'].value)
cat
And you can control the equality of the members:
>>>Animal['Persian cat'] == Animal['Bengal cat']
True
But then your enum class becomes very close to a plain dict
. If additionaly you intend to be able to add new members, then IMHO, it is a hint that what you want is not an Enum
but a simple dict
.
CodePudding user response:
The easiest method would be to use the MultiEnum
from aenum
:
from aenum import MultiValueEnum
class Animal(MultiValueEnum):
CAT = 'Cat', 'Persian cat', 'Bengal cat', 'Siamese cat'
DOG = 'Dog', 'Greyhound', 'Boxer', 'Great Dane'
def __repr__(self):
# make the repr not reduntant
return "<%s.%s>" % (self.__class__.__name__, self.name)
and in use:
>>> Animal('Bengal cat')
<Animal.CAT>
>>>> Animal('Boxer')
<Animal.DOG>
If you need to stick with the stdlib version of Enum
:
from enum import Enum
class Animal(Enum):
#
def __new__(cls, *values):
member = object.__new__(cls)
member._value_ = values[0]
member.all_values = values
return member
#
@classmethod
def _missing_(cls, value):
for member in cls:
if value in member.all_values:
return member
#
CAT = 'Cat', 'Persian cat', 'Bengal cat', 'Siamese cat'
DOG = 'Dog', 'Greyhound', 'Boxer', 'Great Dane'
def __repr__(self):
# make the repr not reduntant
return "<%s.%s>" % (self.__class__.__name__, self.name)
Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.