2014-10-27 19 views
6

Perché può in Python dell'uguaglianza 3 enum non essere controllato in modo corretto attraverso i confini del modulo se l'enum è stato definito nel modulo principale? Ecco un esempio:Python enumerazioni attraverso moduli

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" sui rendimenti della riga di comando:

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 

decommentando l'operatore di uguaglianza personalizzato nella enum porta ad un'affermazione fail lì. Ho trovato che il modulo di classe non è lo stesso in entrambi i casi, in quanto è "__main__" in un caso.

Qual è la "via Pythonic" la maggior parte per risolvere questo problema (altro che spostare l'enumerazione al proprio modulo)?

EDIT: passaggio a "avariable è bVariable" non funziona neanche:

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 

risposta

10

Per quanto riguarda Python è interessato, si dispone di tre moduli qui:

  • __main__
  • moduleA
  • moduleB

Il file eseguito dalla riga di comando, il punto di ingresso principale, viene sempre memorizzato come modulo __main__. Se si importa moduleA in qualsiasi punto del codice, Python lo vede come separato dal modulo __main__ e crea invece un nuovo oggetto modulo. Avete così due separati MyEnum classi:

  • __main__.MyEnum
  • moduleA.MyEnum

I loro membri sono distinte e quindi non può essere uguale.

Il test passa, se invece di usare import moduleA si è utilizzato import __main__ as moduleA, o utilizzato un file separato script per guidare la prova; che file separato sarebbe diventato __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) 

Un'altra soluzione potrebbe essere quella di dire a Python che __main__ e moduleA sono la stessa cosa; prima importare moduleA (o moduleB, che importa moduleA) è possibile aggiungere un'altra voce al sys.modules:

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

import moduleB 

non piacerebbe prendere in considerazione questo molto Pythonic.