How do I test if int value exists in Python Enum without using try/catch?
test for values
variant 1
note that an Enum
has a member called _value2member_map_
(which is undocumented and may be changed/removed in future python versions):
print(Fruit._value2member_map_)# {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>}
you can test if a value is in your Enum
against this map:
5 in Fruit._value2member_map_ # True7 in Fruit._value2member_map_ # False
variant 2
if you do not want to rely on this feature this is an alternative:
values = [item.value for item in Fruit] # [4, 5, 6]
or (probably better): use a set
; the in
operator will be more efficient:
values = set(item.value for item in Fruit) # {4, 5, 6}
then test with
5 in values # True7 in values # False
add has_value
to your class
you could then add this as a method to your class:
class Fruit(Enum): Apple = 4 Orange = 5 Pear = 6 @classmethod def has_value(cls, value): return value in cls._value2member_map_ print(Fruit.has_value(5)) # Trueprint(Fruit.has_value(7)) # False
test for keys
if you want to test for the names (and not the values) i would use _member_names_
:
'Apple' in Fruit._member_names_ # True'Mango' in Fruit._member_names_ # False
You could use Enum.__members__
- an ordered dictionary mapping names to members:
In [12]: 'Apple' in Fruit.__members__Out[12]: TrueIn [13]: 'Grape' in Fruit.__members__Out[13]: False
There is a way to have all the enums be able to check if an item is present:
import enum class MyEnumMeta(enum.EnumMeta): def __contains__(cls, item): return item in [v.value for v in cls.__members__.values()] class MyEnum(enum.Enum, metaclass=MyEnumMeta): FOO = "foo" BAR = "bar"
Now you can do an easy check:
>>> "foo" in MyEnumTrue
It can even be made simpler if all the enum's values will always be the same type -- for example strings:
import enum class MyEnumMeta(enum.EnumMeta): def __contains__(cls, item): return item in cls.__members__.values()class MyEnum(str, enum.Enum, metaclass=MyEnumMeta): FOO = "foo" BAR = "bar"
Edit: Yet another version, technically the most correct one:
import enum class MyEnumMeta(enum.EnumMeta): def __contains__(cls, item): try: cls(item) except ValueError: return False else: return Trueclass MyEnum(enum.Enum, metaclass=MyEnumMeta): FOO = "foo" BAR = "bar"