Посмотрите на следующую информацию от PEP 328 :
Относительный импорт использует атрибут модуля __name__
, чтобы определить позицию этого модуля в иерархии пакетов. Если имя модуля не содержит никакой информации о пакете (например, оно установлено на '__main__'
), то относительный импорт разрешается так, как если бы модуль был модулем верхнего уровня, независимо от того, где этот модуль фактически находится в файловой системе.
Когда вы запускаете foo.py
как скрипт, для этого модуля __name__
равен '__main__'
, поэтому вы не можете выполнить относительный импорт. Это было бы верно, даже если бы mypackage
был на sys.path
. По сути, вы можете выполнять относительный импорт из модуля, только если этот модуль был импортирован.
Вот несколько вариантов решения этой проблемы:
1) В foo.py
проверьте, если __name__ == '__main__'
, и условно добавьте mypackage
к sys.path
:
if __name__ == '__main__':
import os, sys
# get an absolute path to the directory that contains mypackage
foo_dir = os.path.dirname(os.path.join(os.getcwd(), __file__))
sys.path.append(os.path.normpath(os.path.join(foo_dir, '..', '..')))
from mypackage import bar
else:
from .. import bar
2) Всегда импортируйте bar
, используя from mypackage import bar
, и выполняйте foo.py
таким образом, чтобы mypackage
автоматически отображалось:
$ cd <path containing mypackage>
$ python -m mypackage.foo.foo