Решение - как уже упоминалось - состоит в том, чтобы избежать рекурсивного import
основного модуля, но borg.py
означает , а не , который "импортируется дважды". Проблема в том, что при импорте на всех , когда он уже выполняется, вы определяете класс Borg
дважды в двух разных пространствах имен.
Для демонстрации я добавил несколько строк вверху borg.py
и borg2.py
и вставил свою функцию print_module
до и после большинства интересных мест:
#!/usr/bin/env python2
from __future__ import print_function
def print_module(*args, **kwargs):
print(__name__ + ': ', end='')
print(*args, **kwargs)
return
print_module('Importing module borg2...')
import borg2
print_module('Module borg2 imported.')
print_module('Defining class Borg...')
class Borg:
...
# etc.
Вывод:
__main__: Importing module borg2...
borg2: Importing module borg...
borg: Importing module borg2...
borg: Module borg2 imported.
borg: Defining class Borg...
borg: id(_we_are_one) = 17350480
borg: Class Borg defined.
borg: id(Borg) = 139879572980464
borg: End of borg.py.
borg2: Module borg imported.
borg2: End of borg2.py.
__main__: Module borg2 imported.
__main__: Defining class Borg...
__main__: id(_we_are_one) = 17351632
__main__: Class Borg defined.
__main__: id(Borg) = 139879572981136
__main__: Borg 17351632
__main__: Borg 17351632
__main__: Bjorn
borg: Borg 17350480
borg2: ?
__main__: End of borg.py.
Первое, что делает borg.py
(не считая добавленных мною битов), это импорт borg2
в пространство имен __main__
. Это происходит до того, как класс Borg
определен где-либо.
Первое, что делает borg2
, это импорт borg
, который снова пытается импортировать borg2
... и Python отказывается это сделать. (Обратите внимание, что ничего не происходит между строками 3 и 4.) borg
наконец определяет класс Borg
и функцию fct_ab
в пространстве имен borg
и завершает работу.
borg2
затем определяет fct_c
и выходит ("borg2: Конец borg2.py."). Все операторы import
выполнены.
Теперь borg.py
наконец выполнится «по-настоящему». Да, он уже запускался один раз, когда импортировался, но это все еще «первый раз» в файле borg.py
. Класс Borg
снова определяется, на этот раз в пространстве имен __main__
, и у класса, и у его словаря новые идентификаторы.
borg.py
не был "импортирован дважды". Он был выполнен один раз из командной строки и один раз был выполнен при импорте. Поскольку это произошло в двух разных пространствах имен, «второе» определение Borg
не заменило первое, и две функции изменили два разных класса, которые просто оказались созданы из одного и того же кода.