Enum的使用场景一般都是在某一个数据结构中,某一个字段的值是几个固定的值,比方说
from enum import Enum
class Status(Enum):
RUNNING = "running"
STOPPED = "stopped"
ERROR = "error"
假设你作为服务端,可能从接口定义上来看,Status 这个字段只能有3个值
- running
- pending
- error
但是实际上客户端发来的数据我们是没办法保证的,如果它发来一个 closing ,用Enum类直接通过closing这个值来parse出Status是不可能的
>>> Status("closing")
ValueError: 'closing' is not a valid Status
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/shaokaix/ENV/python3.7/lib/python3.7/enum.py", line 310, in __call__
return cls.__new__(cls, value)
File "/home/shaokaix/ENV/python3.7/lib/python3.7/enum.py", line 564, in __new__
raise exc
File "/home/shaokaix/ENV/python3.7/lib/python3.7/enum.py", line 548, in __new__
result = cls._missing_(value)
File "/home/shaokaix/ENV/python3.7/lib/python3.7/enum.py", line 577, in _missing_
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 'closing' is not a valid Status
为了避免这种情况,可能需要做一些处理,比如说:
try:
status = Status(value)
except ValueError:
status = Status.ERROR
其实还有另一种神奇的方式可以在Enum类中直接给定默认值,通过重写_missing_方法,如下
class Status(Enum):
RUNNING = "running"
STOPPED = "stopped"
ERROR = "error"
UNKNOWN = "unknown"
@classmethod
def _missing_(cls, value: object) -> "Status":
""" Overwrite from Enum to set a default return when value is not defined in Status
Args:
value: the undefined value
Returns:
Default Status
"""
logger.warning("%s is not defined in %s, use default value: %s", value, cls.__name__, Status.UNKNOWN)
return Status.UNKNOWN
if __name__ == '__main__':
print(Status("closing"))
# 输出如下
closing is not defined in Status, use default value: Status.UNKNOWN
Status.UNKNOWN