2014-10-27 77 views
6

爲什麼在Python 3中枚舉相等性不能在模塊邊界上正確檢查,如果在主模塊中定義了枚舉?下面是一個例子:跨模塊的Python枚舉

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 

調用 「./moduleA.py」 上的命令行收率:

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 

取消註釋enum中的自定義相等運算符會導致斷言失敗在那裏。我發現在這兩種情況下類模塊都不一樣,因爲在一種情況下它是「__main__」。

什麼是解決這個問題的最「Python方法」(除了將枚舉移動到它自己的模塊之外)?

編輯:切換到 「aVariable是bVariable」 不工作之一:

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 

回答

10

至於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 

我不認爲這是非常Python化。