python - Python 中的枚举无法按预期工作

标签 python python-3.x enums enumeration

我在 Python 的 Enum 类中发现了一个非常奇怪的行为。所以枚举类型很简单:

from enum import Enum
Analysis = Enum('Analysis', 'static dynamic')

所以我在step对象中使用了这个枚举类型,让他们把它存储在属性分析中,如下:

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

这是不正确的,但我不知道如何调试它。

更新

按照@martineau 的建议,我创建了一个 IntEnum 来解决我的问题。然而,我不明白为什么普通的 Enum 不起作用。

最佳答案

在评论中,你说:

The input file contains many steps, and every time I add a new step I have to set up the analysis type

如果我没理解错的话,你是说每次添加新步骤时都会创建一个新的 Enum 对象。这可能就是您看到“错误”的原因。两个不同的 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

为什么有EnumIntEnum

乍一看,IntEnum 似乎总是我们想要的。那么 Enum 有什么意义呢?

假设您要枚举两组项目,例如,水果和颜色。现在,“橙色”既是一种水果,也是一种颜色。所以我们写:

Fruits = enum.IntEnum("Fruits", "orange apple lemon")
Colors = enum.IntEnum("Colors", "orange red blue")

但是现在:

>>> Fruits.orange == Colors.orange
True

但是,从哲学上讲,“橙色”(水果)与“橙色”(颜色)不同!我们不应该能够区分这两者吗?在这里,IntEnumint 的子类化对我们不利,因为 Fruits.orangeColors.orange 等同到 1。当然,正如我们在上面看到的,Enum 的比较是比较 id,而不是值。由于 Fruits.orangeColors.orange 是唯一的对象,因此它们不相等:

Fruits = enum.Enum("Fruits", "orange apple lemon")
Colors = enum.Enum("Colors", "orange red blue")

这样:

>>> Fruits.orange == Colors.orange
False

而且我们不再生活在这样一个世界中,您可以在本地杂货店的农产品区找到一些颜色。

关于python - Python 中的枚举无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28125055/

相关文章:

Python:如何在 Tkinter 中将相对坐标转换为绝对坐标

java - 如何使用 python 连接到 JMX 代理

python - 有没有办法使用 Twilio python Lookup api 打印输出并使用找到的调用者名称作为变量?

jsf - 如何测试 JSF 中的枚举相等性?

python - 如何使用 pybind11 提供默认枚举值?

python、pandas、数据框、行到列

python - 如何向 sqlalchemy 中的表添加自定义的任意选项?

python-3.x - 如何选择 Pandas 中每个唯一记录的最后 5 行

python - 当指定 `return 1` 时,为什么 Python 函数返回 1.0( float )?

java - 在 Java 中使用枚举