Home > OS >  Idiomatic way to check if a value is inside an Enum
Idiomatic way to check if a value is inside an Enum

Time:07-08

I want to check if some string value exists in the values set of some Enum. Here is what I do:

from enum import Enum

class Color(str, Enum):

    RED = "red"
    GREEN = "green"
    YELLOW = "yellow"

s = "red"
# s = "blue"

if any(s == c.value for c in Color):
    print(Color(s))

When I checked the documentation I found that:

The EnumMeta metaclass is responsible for providing the contains(), dir(), iter() and other methods that allow one to do things with an Enum class that fail on a typical class, such as list(Color) or some_enum_var in Color

But I want something different (checking existence for values). Is there a more pythonic way to solve this?

CodePudding user response:

In Python 3.12 you'll be able to do this directly with in:

>>> "red" in Color
<stdin>:1: DeprecationWarning: in 3.12 __contains__ will no longer raise TypeError, but will return True if
obj is a member or a member's value
...
TypeError: unsupported operand type(s) for 'in': 'str' and 'EnumMeta'

While we're waiting for that, though, one option in addition to the one you've already found is to pass your value to the constructor, which will return the appropriate enum instance if there's a matching value, and raise ValueError otherwise.

>>> Color("red")
<Color.RED: 'red'>
>>> Color("asdf")
Traceback (most recent call last):
...
ValueError: 'asdf' is not a valid Color

CodePudding user response:

You can test values against _value2member_map_, a dict attribute of the Enum sub-class that maps values to member classes, if you prefer not to clutter up your code with a try-except block:

if s in Color._value2member_map_:
    print(Color(s))
  • Related