I have created the following Enum:
JavaScript
x
7
1
from enum import Enum
2
3
class Action(str, Enum):
4
NEW_CUSTOMER = "new_customer"
5
LOGIN = "login"
6
BLOCK = "block"
7
I have inherited from str
, too, so that I can do things such as:
JavaScript
1
5
1
action = "new_customer"
2
3
if action == Action.NEW_CUSTOMER:
4
5
I would now like to be able to check if a string is in this Enum, such as:
JavaScript
1
3
1
if "new_customer" in Action:
2
.
3
I have tried adding the following method to the class:
JavaScript
1
3
1
def __contains__(self, item):
2
return item in [i for i in self]
3
However, when I run this code:
JavaScript
1
3
1
print("new_customer" in [i for i in Action])
2
print("new_customer" in Action)
3
I get this exception:
JavaScript
1
8
1
True
2
Traceback (most recent call last):
3
File "/Users/kevinobrien/Documents/Projects/crazywall/utils.py", line 24, in <module>
4
print("new_customer" in Action)
5
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/enum.py", line 310, in __contains__
6
raise TypeError(
7
TypeError: unsupported operand type(s) for 'in': 'str' and 'EnumMeta'
8
Advertisement
Answer
I just bumped into this problem today (2020-12-09); I had to change a number of subpackages for Python 3.8.
Perhaps an alternative to the other solutions here is the following, inspired by the excellent answer here to a similar question, as well as @MadPhysicist’s answer on this page:
JavaScript
1
20
20
1
from enum import Enum, EnumMeta
2
3
4
class MetaEnum(EnumMeta):
5
def __contains__(cls, item):
6
try:
7
cls(item)
8
except ValueError:
9
return False
10
return True
11
12
13
class BaseEnum(Enum, metaclass=MetaEnum):
14
pass
15
16
17
class Stuff(BaseEnum):
18
foo = 1
19
bar = 5
20
Tests (python >= 3.7
; tested up to 3.10):
JavaScript
1
15
15
1
>>> 1 in Stuff
2
True
3
4
>>> Stuff.foo in Stuff
5
True
6
7
>>> 2 in Stuff
8
False
9
10
>>> 2.3 in Stuff
11
False
12
13
>>> 'zero' in Stuff
14
False
15