Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting enum object from string when enum values are tuples?

Tags:

python

enums

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?

like image 958
KDecker Avatar asked Sep 02 '25 16:09

KDecker


1 Answers

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...?

like image 121
Thijs van Dien Avatar answered Sep 05 '25 10:09

Thijs van Dien