跨模块的Python枚举

问题描述 投票:0回答:1

如果枚举已在主模块中定义,为什么在 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 module enums
1个回答
25
投票

就 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。

© www.soinside.com 2019 - 2024. All rights reserved.