我不明白为什么当我将dict分配为每个成员的值时,这个枚举没有我定义的所有成员:
from enum import Enum
class Token(Enum):
facebook = {
'access_period': 0,
'plan_name': ''}
instagram = {
'access_period': 0,
'plan_name': ''}
twitter = {
'access_period': 0,
'plan_name': ''}
if __name__ == "__main__":
print(list(Token))
输出为:
[<Token.twitter: {'plan_name': '', 'access_period': 0}>]
…但是我期望的是:
[<Token.facebook: {'plan_name': '', 'access_period': 0}>,
<Token.instagram: {'plan_name': '', 'access_period': 0}>,
<Token.twitter: {'plan_name': '', 'access_period': 0}>]
为什么没有显示所有成员?
枚举为成员执行唯一值。成员定义与其他定义相同的值将被视为别名。
演示:
Token.__members__
# OrderedDict([('twitter',
# <Token.twitter: {'plan_name': '', 'access_period': 0}>),
# ('facebook',
# <Token.twitter: {'plan_name': '', 'access_period': 0}>),
# ('instagram',
# <Token.twitter: {'plan_name': '', 'access_period': 0}>)])
assert Token.instagram == Token.twitter
定义的名称都存在,但是它们都映射到同一成员。
如果您有兴趣,请查看源代码:
# [...]
# 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
else:
# Aliases don't appear in member names (only in __members__).
enum_class._member_names_.append(member_name)
# performance boost for any member that would not shadow
# a DynamicClassAttribute
if member_name not in base_attributes:
setattr(enum_class, member_name, enum_member)
# now add to _member_map_
enum_class._member_map_[member_name] = enum_member
try:
# This may fail if value is not hashable. We can't add the value
# to the map, and by-value lookups for this value will be
# linear.
enum_class._value2member_map_[value] = enum_member
except TypeError:
pass
# [...]
此外,在我看来,您想利用枚举类以在运行时修改值(字典(。对于其他人使用您的代码阅读/阅读/使用您的代码,这是强烈灰心的,并且非常不直觉。预计枚举将由常数制成。
如@michaelhoff所指出的,Enum
的行为是考虑具有相同值的名称为Aliases 1 。
您可以使用Advanced Enum
2 库来解决此问题:
from aenum import Enum, NoAlias
class Token(Enum):
_settings_ = NoAlias
facebook = {
'access_period': 0,
'plan_name': '',
}
instagram = {
'access_period': 0,
'plan_name': '',
}
twitter = {
'access_period': 0,
'plan_name': '',
}
if __name__ == "__main__":
print list(Token)
输出现在是:
[
<Token.twitter: {'plan_name': '', 'access_period': 0}>,
<Token.facebook: {'plan_name': '', 'access_period': 0}>,
<Token.instagram: {'plan_name': '', 'access_period': 0}>,
]
加强迈克尔所说的话:Enum
成员是常数 - 除非您真的知道自己在做什么,否则您不应该使用非恒定值。
使用NoAlias
的更好示例:
class CardNumber(Enum):
_order_ = 'EIGHT NINE TEN JACK QUEEN KING ACE' # only needed for Python 2.x
_settings_ = NoAlias
EIGHT = 8
NINE = 9
TEN = 10
JACK = 10
QUEEN = 10
KING = 10
ACE = 11
1 请参阅标准Enum
使用的答案。
2 披露:我是Python STDLIB Enum
,enum34
Backport和Advanced Eneumeration(aenum
(库的作者。