如果枚举已在主模块中定义,为什么在 Python 3 中不能跨模块边界正确检查枚举相等性?这是一个例子:
模块A.py:
#!/usr/bin/python3
import moduleB
from enum import Enum, unique
@unique
class MyEnum(Enum):
A = 1
B = 2
# def __eq__(self,other):
# assert isinstance(other,self.__class__)
# return self.value == other.value
if __name__ == "__main__":
myVar = MyEnum.B
moduleB.doStuff(myVar)
moduleB.py:
#!/usr/bin/python3
import moduleA
def doStuff(aVariable):
bVariable = moduleA.MyEnum.B
assert aVariable == bVariable
在命令行上调用“./moduleA.py”会产生:
Traceback (most recent call last):
File "./moduleA.py", line 17, in <module>
moduleB.doStuff(myVar)
File "/home/myuser/testing/moduleB.py", line 7, in doStuff
assert aVariable == bVariable
AssertionError
取消注释枚举中的自定义相等运算符会导致断言失败。我发现这两种情况下的类模块并不相同,因为在一种情况下它是“__main__”。
解决此问题的最“Pythonic 方法”是什么(除了将枚举移至其自己的模块之外)?
编辑:切换到“aVariable is bVariable”也不起作用:
Traceback (most recent call last):
File "./moduleA.py", line 17, in <module>
moduleB.doStuff(myVar)
File "/home/myuser/testing/moduleB.py", line 7, in doStuff
assert aVariable is bVariable
AssertionError
就 Python 而言,这里有三个模块:
__main__
moduleA
moduleB
从命令行运行的文件(主入口点)始终存储为
__main__
模块。如果您在代码中的任何位置导入 moduleA
,Python 会将其视为与 __main__
模块分离,并创建一个新的模块对象。因此,你有两个独立的MyEnum
类:
__main__.MyEnum
moduleA.MyEnum
他们的成员是不同的,因此不可能是平等的。
如果您使用
import moduleA
而不是使用 import __main__ as moduleA
,或者使用 单独的 脚本文件来驱动测试,则测试通过;该单独的文件将变成 __main__
:
#!/usr/bin/python3
# test.py, separate from moduleA.py and moduleB.py
import moduleA
import moduleB
if __name__ == "__main__":
myVar = moduleA.MyEnum.B
moduleB.doStuff(myVar)
另一种解决方法是告诉 Python
__main__
和 moduleA
是同一件事; 在导入 moduleA
(或
moduleB
,导入
moduleA
)之前,您可以向
sys.modules
添加另一个条目:
if __name__ == '__main__':
import sys
sys.modules['moduleA'] = sys.modules['__main__']
import moduleB
我不认为这很Pythonic。