2014-10-27 14 views
6

Dlaczego w programie Python 3 równanie enum może nie być poprawnie sprawdzane w obrębie granic modułu, jeśli wyliczenie zostało zdefiniowane w module głównym? Oto przykład:Wyliczenia Pythona w modułach

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 

Wywoływanie "./moduleA.py" na plony wiersza poleceń:

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 

Odkomentowanie niestandardowego operatora równości w wyliczeniu prowadzi do niepowodzenia asercji jesteś tam. Odkryłem, że moduł klasy nie jest taki sam w obu przypadkach, ponieważ jest "__main__" w jednym przypadku.

Jaki jest najbardziej "Pythoniczny sposób" rozwiązania tego problemu (poza przeniesieniem enum do własnego modułu)?

EDIT: Przejście na "aVariable jest bVariable" nie działa albo:

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 

Odpowiedz

10

miarę Python jest zainteresowana, masz trzy moduły tutaj:

  • __main__
  • moduleA
  • moduleB

Plik uruchamiany z wiersza poleceń, główny punkt wejścia, jest zawsze przechowywany jako moduł __main__. Jeśli importujesz moduleA w dowolnym miejscu kodu, Python widzi to jako oddzielne od modułu __main__ i tworzy zamiast niego nowy obiekt modułu. Ci zatem mieć dwa oddzielne MyEnum klasy:

  • __main__.MyEnum
  • moduleA.MyEnum

Ich członkowie są różne i dlatego nie mogą być równe.

test przechodzi jeżeli zamiast korzystania import moduleA użyłeś import __main__ as moduleA lub użył osobny plik skryptu do prowadzenia badań; że oddzielny plik staną __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) 

Innym Rozwiązaniem byłoby powiedzieć, że __main__ Python i moduleA to samo; przed importującego moduleA (lub moduleB, która importuje moduleA) można dodać kolejny wpis do sys.modules:

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

import moduleB 

Nie chciałbym rozważyć to bardzo pythonowy.