2014-10-27 4 views
6

Почему в правиле Python 3 равномерно не проверяется правильность границ модуля, если перечисление было определено в основном модуле? Вот пример:Python Enums через модули

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 

Разоблачение пользовательского оператора равенства в перечислении приводит к ошибке утверждения там. Я обнаружил, что модуль класса не является одинаковым в обоих случаях, так как это «__main__» в одном случае.

Что является самым «путинским способом» для устранения этой проблемы (кроме перемещения перечисления в собственный модуль)?

EDIT: Переключение на "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 

бы я не считаю, что это очень Pythonic.

Смежные вопросы