python - Python enum.Enum 创建别名而不是新值
问题描述
我刚刚注意到 pyhton 中 Enum+defaultdict 的一个非常奇怪的行为。我定义了一个这样的枚举,它收集了一些默认字典:
from enum import Enum
from collections import defaultdict
class A(Enum):
a = defaultdict(lambda: 1)
b = defaultdict(lambda: 2)
然后,当我查看 A 内部的内容时:
In [11]: A.a
Out[11]: <A.a: defaultdict(<function A.<lambda> at 0x7f773f03b510>, {})>
In [12]: A.b
Out[12]: <A.a: defaultdict(<function A.<lambda> at 0x7f773f03b510>, {})>
所以A.b
只是A.a
. 这对我来说很像一个错误,即使背后可能有一些很好的理由。任何的想法?
附录
因为它出现在评论中,所以要说明为什么要将字典放入枚举中。我发现将常量分组到命名空间中通常很有用,这样人们就可以访问值,如A.a.constant1
,A.b.constant1
等。目前,尝试使用 Enums 这样做会引发AttributeError
. 当然,可以执行以下操作:
class A:
class a(Enum):
constant1 = 1
class b(Enum):
constant1 = 2
但是,这并没有利用 Enum 的功能(迭代、访问__getitem__
等)。
解决方案
如果您给两个枚举成员相同的值,enum
将产生一个具有两个别名的枚举成员,而不是两个不同的成员。
Defaultdicts 从 继承相等比较dict
。这意味着默认工厂不是==
比较的一部分。您的枚举成员具有相同的值,因此它们被合并。
使用可变对象作为枚举值通常是个坏主意。他们倾向于打破enum
“价值平等不变”之类的设计假设。考虑以其他方式将这些默认字典附加到您的枚举成员。
推荐阅读
- c++ - 分支预测是否仍在显着加快数组处理速度?
- python - 使用 Azure Key Vault 和 Active Directory 检索机密
- ansible - 无法在 Debian 伸展的 Ansible 2.7 上使用 NPM 包安装 PM2
- c++ - 'x' 的 GCC 警告声明会影响 y 类的成员
- servicenow - ServiceNow:克隆请求功能不会复制所有请求字段
- python - 为什么通过 conda 启动 jupyter notebook 时出现 python37.dll 错误
- android - 输出顺序显示错误
- cors - 请求的资源上不存在“Access-Control-Allow-Origin”标头。如何在 SWI-Prolog / ClioPatria 中正确处理 CORS 请求?
- c++ - GoogleTest 测试夹具说明
- javascript - javascript 在我的客户端和我的服务器文件夹之间共享代码