While experimenting with different value types for Enum
members, I discovered some odd behavior when the values are mutable.
If I define the values of an Enum
as different lists, the members still behave similarly to when the Enum
values are typical immutable types like str
or int
, even though I can change the values of the members in place so that the values of the two Enum
members are the same:
>>> 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
However, if I define the values to be identical lists, each member's value seems to be the same object, and thus any mutation of one member's value affects all members:
>>> 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
Why does Enum
behave this way? Is it the intended behavior or is it a bug?
NOTE: I'm not planning on actually using Enums this way, I was simply experimenting with using non-standard values for Enum members
By definition, the enumeration member values are unique. However, you can create different member names with the same values.
Enum members should always be declared using UPPER_CASE names since they are constants. Enumerations in Python are immutable.
1. Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.
Enum names are in global scope, they need to be unique.
From the docs:
Given two members A and B with the same value (and A defined first), B is an alias to A. By-value lookup of the value of A and B will return A. By-name lookup of B will also return A:
>>> 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>
This operates by equality, even when the values are mutable. Since you defined equal values for black
and blue
, with black
first, blue
is an alias for black
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With