这有点跟随Why are mutable values in Python Enums the same object?。
如果Enum
的值是可变的(例如list
s等),则可以随时更改这些值。如果Enum
成员按值检索,我认为这会带来一些问题,特别是如果有人无意中更改了Enum
他查找的值:
>>> from enum import Enum
>>> class Color(Enum):
black = [1,2]
blue = [1,2,3]
>>> val_1 = [1,2]
>>> val_2 = [1,2,3]
>>> Color(val_1)
<Color.black: [1, 2]>
>>> Color(val_2)
<Color.blue: [1, 2, 3]>
>>> my_color = Color(val_1)
>>> my_color.value.append(3)
>>> Color(val_2)
<Color.black: [1, 2, 3]>
>>> Color(val_1)
Traceback (most recent call last):
...
ValueError: [1, 2] is not a valid Color
我认为正常的Python习语是好的,暗示用户可以使用mutable作为Enum
值,但只是为了理解他们可能正在打开虫子。
然而,这会引发第二个问题 - 因为你可以按值查找Enum
memeber,并且值可以是可变的,它必须通过hashmap / {{1以外的方式进行查找因为mutable不能是dict
中的key
。
将dict
值限制为仅可变类型以使Enum
可以实现按值查找更有效(虽然,授予,不太灵活)?
答案 0 :(得分:2)
似乎我的第二个问题的答案隐藏在enum.py
的原始代码中。
每个Enum
包含dict
value->member
个 hashable (即不可变)值的对,当你看按值增加Enum
,它会尝试从dict
检索成员。如果该值不是 hashable ,那么它会将brute-force与所有现有Enum
值进行相等性比较,如果找到匹配则返回成员。相关代码位于enum.py
:
try:
if value in cls._value2member_map_:
return cls._value2member_map_[value]
except TypeError:
# not there, now do long search -- O(n) behavior
for member in cls._member_map_.values():
if member._value_ == value:
return member
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
所以好像enum.py
的设计师想要在按值获取Enum
时快速查找,但仍希望为Enum
提供可变值的灵活性价值观(尽管我仍然无法想到一个原因为什么有人会首先想要这个)。
答案 1 :(得分:2)
值得强调的是,根据文档,枚举值可以是任何。
注意Enum成员值成员值可以是任何值:int,str等。 如果确切值不重要,则可以使用自动实例和 将会为您选择适当的值。如果您要小心 将auto与其他值混合。 https://docs.python.org/3/library/enum.html#creating-an-enum
与其他语言的枚举实体有很大的不同。但是,津贴应为一些有趣的可能性提供条件。我喜欢将字符串作为值变体,其中在源代码中使用源代码友好的枚举名称,而枚举值可用于表示目的,如前端代码或控制台应用程序帮助文本或其他内容。