模块间的Python枚举 [英] Python Enums across Modules

查看:120
本文介绍了模块间的Python枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在主模块中定义了枚举,那么为什么Python 3枚举的等式不能在模块边界之间正确检查?这是一个例子:



moduleA.py:

 #! / usr / bin / python3 

import moduleB
从枚举导入枚举,唯一

@unique
class MyEnum(枚举):
A = 1
B = 2
#def __eq __(self,other):
#assert isinstance(other,self .__ class__)
#return self.value == other。值

如果__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 可以得到: / p>

 追溯(最近的最后一次呼叫):
文件./moduleA.py,第17行,模块>
moduleB.doStuff(myVar)
文件/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py,第7行,doStuff
assert aVariable == bVariable
AssertionError

取消注释枚举中的自定义相似运算符会导致断言失败。我发现在这两种情况下,类模块是不一样的,因为在一种情况下它是__main__。



解决这个问题的最Pythonic方式是什么(除了将枚举移至自己的模块之外)?



编辑:切换到aVariable is bVariable不起作用:

 追溯(最近呼叫最后):
文件./moduleA.py,第17行,< module>
moduleB.doStuff(myVar)
文件/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py,第7行,doStuff
assert aVariable是bVariable
AssertionError


解决方案

就Python而言,您有三个模块:




  • __ main __ / li>
  • moduleA

  • moduleB / li>


从命令行运行的文件,主入口点始终存储为 __ main __ 模块。如果您在代码中的任何地方导入 moduleA ,Python会将其视为与 __ main __ 模块分离,并创建一个新模块目的。因此,您有两个单独的 MyEnum 类:




  • __ main __。MyEnum

  • moduleA.MyEnum



他们的成员是不同的,因此不能相等。



如果您的测试通过,而不是使用 import moduleA 您使用 import __main__作为moduleA ,或者使用单独的脚本文件来驱动测试;该单独的文件将成为 __ main __

 #!/ usr / bin / python3 
#test.py,与moduleA.py和moduleB.py分开

import moduleA
import moduleB

如果__name__ ==__main__ :
myVar = moduleA.MyEnum.B
moduleB.doStuff(myVar)



<另一个解决办法是告诉Python, __ main __ moduleA 是一样的; 导入 moduleA (或 moduleB ,导入 moduleA ),您可以添加另一个条目到 sys.modules

 如果__name__ =='__main__':
import sys
sys.modules ['moduleA'] = sys.modules ['__ main__']

import moduleB

我不认为这是非常Pythonic。


Why can in Python 3 enum equality not be checked correctly across module boundaries if the enum has been defined in the main module? Here is an example:

moduleA.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

Calling "./moduleA.py" on the command line yields:

Traceback (most recent call last):
  File "./moduleA.py", line 17, in <module>
    moduleB.doStuff(myVar)
  File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff
    assert aVariable == bVariable
AssertionError

Uncommenting the custom equality operator in the enum leads to an assertion failure there. I've found that the class module is not the same in both cases, as it is "__main__" in one case.

What is the most "Pythonic way" to fix this problem (other than moving the enum to its own module)?

EDIT: Switching to "aVariable is bVariable" does not work either:

Traceback (most recent call last):
  File "./moduleA.py", line 17, in <module>
    moduleB.doStuff(myVar)
  File "/home/ruedi/Dropbox/Reps/stuffed/sosy/testing/moduleB.py", line 7, in doStuff
    assert aVariable is bVariable
AssertionError

解决方案

As far as Python is concerned, you have three modules here:

  • __main__
  • moduleA
  • moduleB

The file you run from the command line, the main entry point, is always stored as the __main__ module. If you import moduleA anywhere in the code, Python sees that as separate from the __main__ module and creates instead a new module object. You thus have two separate MyEnum classes:

  • __main__.MyEnum
  • moduleA.MyEnum

Their members are distinct and thus cannot be equal.

Your test passes if instead of using import moduleA you used import __main__ as moduleA, or used a separate script file to drive the test; that separate file would become __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)

Another workaround would be to tell Python that __main__ and moduleA are the same thing; before importing moduleA (or moduleB, which imports moduleA) you can add another entry to sys.modules:

if __name__ == '__main__':
    import sys
    sys.modules['moduleA'] = sys.modules['__main__']

import moduleB

I'd not consider this very Pythonic.

这篇关于模块间的Python枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆