2

我有MyEnum一个从 派生的枚举enum,在文件中定义,myenum.py例如:

# myenum.py
import enum

class MyEnum(enum.Enum):
    ONE = 1
    TWO = 2

importlib.import_module()然后,我使用该方法导入此文件。我创建a了我的枚举实例,并测试了它的值:它是正确的,如预期的那样。

但是,如果我重新加载我的文件,使用importlib.reload(),a不再等于MyEnum.ONE. 这是什么原因造成的?我在 Python 3.7 上。

# test.py
import importlib

def test_enum(e):
    print(e, myenum.MyEnum.ONE)
    print("test is :", e==myenum.MyEnum.ONE)

if __name__=='__main__':
    globals()["myenum"] = importlib.import_module("myenum")
    a = myenum.MyEnum.ONE
    test_enum(a)
    importlib.reload(globals()["myenum"])
    test_enum(a)

结果

MyEnum.ONE MyEnum.ONE
test is : True
MyEnum.ONE MyEnum.ONE
test is : False

编辑:经过进一步研究,Python 中的枚举似乎是通过 ID 进行比较的。但是,当重新导入模块时,我的枚举的 ID 发生了变化,这就是比较返回的原因False

有哪些选项可以避免此 ID 更改允许比较保持 True ?

4

2 回答 2

2
  1. 无法避免ID更改;你用新实例创建了一个新类,而现有类的实例仍然存在;从定义上讲,ID不允许相等。

  2. 如果您必须允许他们在身份不同的情况下进行比较,您可以覆盖做任何您喜欢__eq__的事情,例如:enum

    class MyEnum(enum.Enum):
        ONE = 1
        TWO = 2
        def __eq__(self, other):
            if type(self).__qualname__ != type(other).__qualname__:
                return NotImplemented
            return self.name == other.name and self.value == other.value
    
        def __hash__(self):
            return hash((type(self).__qualname__, self.name))
    

    我不建议这样做(正确使用enums 将is用于比较,并且没有什么可以使它起作用,因为它依赖于 ID,每个点 #1总是不同的),而且速度会慢得多(删除s)的好处之一enum,但如果reload在开发过程中必须允许,它是可行的。只要确保删除reload生产代码。

于 2021-03-11T02:01:43.370 回答
0

你不能保证MyEnum总是指同一个类。但是实例e本身总是引用同一个类。因此,一种解决方法是将您的测试更改为:

print("test is :", e==type(e).ONE)
于 2022-02-15T21:41:05.170 回答