Bil*_*lly 18 python enums identity python-3.x
在为Enum成员试验不同的值类型时,我发现当值是可变的时会有一些奇怪的行为.
如果我将一个值定义Enum为不同的列表,那么成员的行为仍然类似于Enum值是典型的不可变类型,如str或int,即使我可以更改成员的值,以便两个Enum成员的值相同:
>>> class Color(enum.Enum):
black = [1,2]
blue = [1,2,3]
>>> Color.blue is Color.black
False
>>> Color.black == Color.blue
False
>>> Color.black.value.append(3)
>>> Color.black
<Color.black: [1, 2, 3]>
>>> Color.blue
<Color.blue: [1, 2, 3]>
>>> Color.blue == Color.black
False
>>> Color.black.value == Color.blue.value
True
Run Code Online (Sandbox Code Playgroud)
但是,如果我将值定义为相同的列表,则每个成员的值似乎是同一个对象,因此一个成员的值的任何突变都会影响所有成员:
>>> class Color(enum.Enum):
black = [1,2,3]
blue = [1,2,3]
>>> Color.blue is Color.black
True
>>> Color.black == Color.blue
True
>>> Color.black.value.append(4)
>>> Color.black
<Color.black: [1, 2, 3, 4]>
>>> Color.blue
<Color.black: [1, 2, 3, 4]>
>>> Color.blue == Color.black
True
Run Code Online (Sandbox Code Playgroud)
为什么Enum这样做?这是预期的行为还是一个错误?
注意: 我不打算以这种方式实际使用Enums,我只是尝试使用Enum成员的非标准值
use*_*ica 10
来自文档:
给定两个具有相同值的成员A和B(并且A定义为第一个),B是A的别名.A和B的值的值按字母顺序查找将返回A.B的名字查找也将返回A:
Run Code Online (Sandbox Code Playgroud)>>> class Shape(Enum): ... square = 2 ... diamond = 1 ... circle = 3 ... alias_for_square = 2 ... >>> Shape.square <Shape.square: 2> >>> Shape.alias_for_square <Shape.square: 2> >>> Shape(2) <Shape.square: 2>
即使值是可变的,这也是平等运作的.由于您为black和定义了相等的值,因此blue,black首先blue是for的别名black.
要补充@ user2357112的答案,请查看EnumMeta所有Enum类的元类; 它可以查看具有类型的每个类定义,并进行更改以更改它.
具体来说,它需要 通过简单的赋值在其__new__方法中重新分配具有相同值的成员:
# If another member with the same value was already defined, the
# new member becomes an alias to the existing one.
for name, canonical_member in enum_class._member_map_.items():
if canonical_member._value_ == enum_member._value_:
enum_member = canonical_member
break
Run Code Online (Sandbox Code Playgroud)
我没有选择检查文档,而是查看源代码.课程:始终检查文档,如果ExplanationNotFound被提出; 检查来源:-)
| 归档时间: |
|
| 查看次数: |
717 次 |
| 最近记录: |