我在Python的Enum类中发现了一个非常奇怪的行为。所以枚举类型很简单:
from enum import Enum
Analysis = Enum('Analysis', 'static dynamic')
因此,我在步骤对象中使用此枚举类型,以便它们将其存储在属性分析中,如下所示:
class Step:
def __init__(self):
self.analysis = None
self.bcs = []
到目前为止非常简单,所以当我在列表中有几个步骤时,我会尝试查看枚举类型,并且它已正确分配。但是它们并不相等:
# loop over steps
for s, step in enumerate(kwargs['steps']):
print(kwargs)
print(step)
print(step.analysis)
print("test for equality: ",(step.analysis == Analysis.static))
quit()
打印
{'mesh': <fem.mesh.mesh.Mesh object at 0x10614d438>,
'steps': [<hybrida.fem.step.Step object at 0x10614d278>,
<hybrida.fem.step.Step object at 0x10616a710>,
<hybrida.fem.step.Step object at 0x10616a390>]}
Step:
analysis: Analysis.static
bcs: [<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a0f0>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a320>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a3c8>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a470>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a518>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a5c0>,
<hybrida.fem.conditions.dirichlet.Dirichlet object at 0x10616a668>]
Analysis.static
test for equality: False
这是不正确的,但是我不知道如何调试它。
UPDATE
根据@martineau的建议,我改为创建了一个IntEnum
,这解决了我的问题。但是,我不明白为什么正常的Enum
无法正常工作。
在评论中,您说:
输入文件包含许多步骤,并且每次我添加一个新步骤时,必须设置分析类型
如果我对您的理解正确,您是说每次添加新步骤时都会创建一个新的Enum
对象。这可能就是为什么您看到“ bug”的原因。尽管两个不同的Enum
对象的名称和顺序相同,但它们的值不一定相等。例如:
import enum
Analysis1 = enum.Enum("Analysis", "static dynamic")
Analysis2 = enum.Enum("Analysis", "static dynamic")
但是:
>>> Analysis1.static == Analysis2.static
False
这是因为据我所知,没有为Enum
对象定义相等运算符,所以使用了检查id
的默认行为。
正如@martineau在评论中建议的那样,避免此问题的一种方法是改用IntEnum
类型,该类型是int
的子类,因此根据Enum
的值定义了相等运算符,而不是id
:
import enum
Analysis1 = enum.IntEnum("Analysis", "static dynamic")
Analysis2 = enum.IntEnum("Analysis", "static dynamic")
然后:
>>> Analysis1.static == Analysis2.static
True
Enum
和 IntEnum
?乍看之下IntEnum
似乎是[[总是我们想要的。那么Enum
的意义是什么?
Fruits = enum.IntEnum("Fruits", "orange apple lemon")
Colors = enum.IntEnum("Colors", "orange red blue")
但是现在:
>>> Fruits.orange == Colors.orange True
但是,从哲学上讲,“橙色”(水果)与“橙色”(颜色)不同!我们不应该能够区分两者吗?此处,int
的IntEnum
子类对我们不利,因为Fruits.orange
和Colors.orange
都等于1
。当然,正如我们在上面看到的,比较Enum
s是比较id
s,而不是值。由于Fruits.orange
和Colors.orange
是唯一的对象,因此它们的比较不相等:
Fruits = enum.Enum("Fruits", "orange apple lemon") Colors = enum.Enum("Colors", "orange red blue")
因此:
>>> Fruits.orange == Colors.orange False
而且我们不再生活在一个可以在当地杂货店的农产品部分找到某些颜色的东西的世界中。
# File: package/module/analysis_types.py
Analysis = enum.Enum("Analysis", "static dynamic")
# File: package/module/static_thing.py
from .analysis_types import Analysis
class StaticThing:
...
analysis = Analysis.static
...
# File: package/module/static_thing_test.py
from package.module.static_thing import StaticThing
from .analysis_types import Analysis
# This throws an AssertionError because as
# id(StaticThink.analysis) != id(Analysis.static)
assert StaticThink.analysis == Analysis.static
通过以下更改恢复了预期的行为:
# File: package/module/static_thing_test.py from .static_thing import StaticThing from .analysis_types import Analysis # This does NOT throw an AssertionError because as # id(StaticThink.analysis) == id(Analysis.static) assert StaticThink.analysis == Analysis.static