#python #python_3x #архитектура #python_35
Пишу на python 3.5, пробую пользовать типизацию, но столкнулся с проблемой циклического импортирования - стало сложно разбивать программу на модули. Одна из проблем отношение одни_к_одному: # модуль 1 from mod1 import B class A: def __init__(self): self.__B = B(self) # модуль 2 from mod2 import A class B: def __init__(self, arg: A): self.__a = arg Ну и так далее. Проблема серьёзно нарастает с увеличением количества модулей. Хочу узнать это я к задаче подхожу неверно, или есть решение проблемы? ПС: я в том смысле, что возбуждается исключение ImportError, и я не могу от него избавиться.
Ответы
Ответ 1
PEP 484 -- Type Hints рекомендует использовать import module вместо from module import Type и задавать типы в виде строк, чтобы уменьшить последствия от круговой зависимости, вызванной использованием type hints: # mod1.py import mod2 class B: def __init__(self, arg: 'mod2.A') -> None: self.__a = arg # mod2.py import mod1 class A: def __init__(self): self.__b = mod1.B(self) В качестве альтернативы, если классы настолько тесно связаны, можно их в один модуль поместить или выполнить другой подходящий случаю refactoring (возможно более общий тип, определённый, к примеру, в mod2.types, следует использовать в B). See Type hinting would generate a lot of import statements (possibly leading to circular imports). Use strings instead of imported names?Ответ 2
def modCreator(): print(''' class A: def __init__(self): from mod1 import B self._B = B(self)''', file=open('mod2.py', 'w')) print(''' from mod2 import A class B: def __init__(self, arg: A): self._a = arg''', file=open('mod1.py', 'w')) if __name__ == '__main__': modCreator() from mod1 import B from mod2 import A a = A() b = B(A) print(a, a._B) print(b, b._a) out:Ответ 3
def modCreate(): modules = {} modules['A.py'] = ''' from G import glob class A: def __init__(self, x: glob.B): self.x = x self.B = glob.B(self) glob.A = A ''' modules['B.py'] = ''' from G import glob class B: def __init__(self, x: glob.A): self.x = x glob.B = B ''' modules['G.py'] = ''' class Glob: def __getattr__(self, class_: object): print('skip %s' % class_) glob = Glob() ''' for module, code in modules.items(): print(code, file=open(module, 'w')) if __name__ == '__main__': modCreate() from B import B from A import A from G import glob print(glob, [[c, getattr(glob, c)] for c in dir(glob) if not c.startswith('_')]) a = A(B) print(a, a.x, a.B) b = B(A) print(b, b.x) print(A == glob.A) out: skip A[['A', ], ['B', ]] True
Комментариев нет:
Отправить комментарий