Reputation: 7128
I have Enum
of the form
class ItemType(Enum):
ITEM1 = ('Desc1', AnotherEnum.ONE)
ITEM2 = ('Desc2', AnotherEnum.TWO)
and I am trying to instantiate an object of the type ItemType
from a JSON string.
For example I would like to get the ItemType
that logically represents the string 'Desc1'
. If the enum values were of the form ITEM1 = 'Desc1'
I could simple do ItemType('Desc1')
. But in the current form I am not sure how I could achieve the lookup method.
Is there a way to do this?
Upvotes: 4
Views: 4221
Reputation: 6616
An Enum
is just a class
, so how about an alternate constructor? It's the most explicit.
class ItemType(Enum):
ITEM1 = ('Desc1', AnotherEnum.ONE)
ITEM2 = ('Desc2', AnotherEnum.TWO)
@classmethod
def from_description(cls, description):
for item in cls:
if item.value[0] == description:
return item
raise ValueError("%r is not a valid %s description" % (description, cls.__name__))
You can then do ItemType.from_description('Desc1')
.
Alternatively, if you want ItemType('Desc1')
to just work, as of Python 3.6 you can implement _missing_
:
class ItemType(Enum):
ITEM1 = ('Desc1', AnotherEnum.ONE)
ITEM2 = ('Desc2', AnotherEnum.TWO)
@classmethod
def _missing_(cls, value):
for item in cls:
if item.value[0] == value:
return item
return super()._missing_(value)
I'd base my choice on whether looking up by description is a natural thing to do or not. If it's specific to translating JSON, rather stick with the alternate constructor. Otherwise, sure, go for this second option. However, in that case I'd wonder if the value is the best place to store the related AnotherEnum
. Maybe instead you should have a method to_another_enum()
, an alternate constructor on AnotherEnum
, or both...?
Upvotes: 8