当对成员值使用相同的字典时,Python Enum显示了奇怪的行为

Far*_*ash 5 python enums dictionary python-3.x

当我为每个成员的值分配一个字典时,我不明白为什么这个枚举没有我定义的所有成员:

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))
Run Code Online (Sandbox Code Playgroud)

输出是:

[<Token.twitter: {'plan_name': '', 'access_period': 0}>]
Run Code Online (Sandbox Code Playgroud)

......但我期待的是:

[<Token.facebook:  {'plan_name': '', 'access_period': 0}>,
 <Token.instagram: {'plan_name': '', 'access_period': 0}>,
 <Token.twitter:   {'plan_name': '', 'access_period': 0}>]
Run Code Online (Sandbox Code Playgroud)

为什么不显示所有成员?

Mic*_*off 5

Enum为成员强制使用唯一值.与其他定义具有相同值的成员定义将被视为别名.

示范:

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
Run Code Online (Sandbox Code Playgroud)

定义的名称都存在,但它们都映射到同一个成员.

如果您有兴趣,请查看源代码:

# [...]
# 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
# [...]
Run Code Online (Sandbox Code Playgroud)

此外,在我看来,您希望利用Enum类在运行时修改值(字典).强烈建议不要这样做,对于阅读/使用您的代码的其他人也非常不直观.枚举预计由常数组成.