Относительный импорт Python в пакете не по пути - PullRequest
4 голосов
/ 26 января 2012

Как я могу импортировать файл, который находится в родительском каталоге в пакете Python (который не находится в пути) в файл в дочернем каталоге?

Я не совсем понимаю словарный запасупаковки python в качестве примера:

dir1/
    __init__.py
    runner.py
    in_dir1.py
    dir2/
        __init__.py
        in_dir2.py

dir1 / in_dir1.py:

def example():
    print "Hello from dir1/in_dir1.example()"

dir1 / dir2 / in_dir2.py

import in_dir1   #or whatever this should be to make this work
print "Inside in_dir2.py, calling in_dir1.example()"
print in_dir1.example()

Учитываячто dir1 не находится на пути Python, я ищу лучший способ импортировать in_dir1 в in_dir2.

Я пытался from .. import in_dir1 и from ..dir1 import in_dir1 на основе этого Q/ A но ни один не работает.Как правильно выполнить это намерение? Этот Q / A , кажется, содержит ответ;однако, я не совсем уверен, что с этим делать / как на самом деле решить мою проблему, используя PEP 366

Оба __init__.py файла пусты, и я на v2.6 .

Я пытаюсь сделать это без использования хаков путей, которые Google продолжает обнаруживать.

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Ответ находится в ссылке, которую вы дали:

Относительный импорт использует атрибут __name__ модуля для определения позиции этого модуля в иерархии пакетов.Если имя модуля не содержит никакой информации о пакете (например, оно установлено на « main »), то относительный импорт разрешается так, как если бы модуль был модулем верхнего уровня, независимо от того, где модуль фактически расположен нафайловая система.

Вы не можете выполнять относительный импорт в __main__ сценариях (т. е. если вы непосредственно запускаете python in_dir2.py).

Чтобы решить эту проблему, PEP 366 позволяет вамdo устанавливает глобальный __package__:

import dir1
if __name__ == '__main__':
    __package__ = 'dir1.dir2'
    from .. import in_dir1

Обратите внимание, что пакет dir1 все еще должен быть на sys.path!Вы можете манипулировать sys.path для достижения этой цели.Но к тому времени чего вы достигли по сравнению с абсолютным импортом?

0 голосов
/ 26 января 2012

Вы можете на самом деле сделать это:

import sys
sys.path.append('..')

, и это будет работать.Но не делай этого.Это может сломать другие модули.

Я думаю, вы можете удалить его сразу после импорта, но не.

РЕДАКТИРОВАТЬ:

На самом деле, это также работает, и я думаю,нет никаких причин, по которым это небезопасно:

внутри in_dir2.py вы можете сделать:

import sys
import os
current_module = sys.modules[__name__]
indir2file=current_module.__file__
sys.path.append(os.path.dirname(os.path.abspath(indir2file))+os.sep+".."+os.sep)
import in_dir1

Вместо этого постарайтесь реструктурировать свой код.

...