4

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?

4
  • 1
    Use a dictionary. Commented Dec 22, 2017 at 0:01
  • In place of the class or the values of the Enum? Commented Dec 22, 2017 at 0:03
  • Use another enum called Desc, then you can do ItemType(Desc('Desc1')) Commented Dec 22, 2017 at 0:18
  • @smac89 Can you turn that into an answer? I'd like to see the full example. Commented Dec 22, 2017 at 1:18

1 Answer 1

8

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.