Импорт из относительного пути в Python - PullRequest
80 голосов
/ 22 сентября 2011

У меня есть папка для кода моего клиента, папка для кода моего сервера и папка для общего кода между ними

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

Как импортировать Common.py из Server.py и Client.py?

Ответы [ 5 ]

119 голосов
/ 22 сентября 2011

РЕДАКТИРОВАТЬ ноябрь 2014 (3 года спустя):

Python 2.6 и 3.x поддерживает правильный относительный импорт, где вы можете избежать каких-либо хакерских действий. Используя этот метод, вы знаете, что вы получаете относительный импорт, а не абсолютный импорт. «..» означает, перейдите в каталог выше меня:

from ..Common import Common

В качестве предупреждения, это будет работать только в том случае, если вы запускаете свой python как модуль из вне пакета. Например:

python -m Proj

Оригинальный хакерский способ

Этот метод все еще широко используется в некоторых ситуациях, когда вы фактически никогда не «устанавливаете» свой пакет. Например, он популярен среди пользователей Django.

Вы можете добавить Common / к вашему sys.path (список путей, которые python просматривает для импорта вещей):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__) просто дает вам каталог, в котором находится ваш текущий файл python, а затем мы переходим в «Common /» каталог и импортируем «Common» модуль.

13 голосов
/ 22 сентября 2011

Не делать относительный импорт.

С PEP8 :

Относительный импорт для внутрипакетного импорта крайне не рекомендуется.

Поместите весь ваш код в один супер-пакет (то есть «myapp») и используйте подпакеты для клиента, сервера и общего кода.

Обновление: Msgstr " Python 2.6 и 3.x поддерживает правильный относительный импорт (...) ". См. Дейв ответы для более подробной информации.

6 голосов
/ 17 апреля 2015

Достаточно забавно, та же проблема, с которой я только что столкнулся, и я получаю эту работу следующим образом:

в сочетании с командой linux ln мы можем упростить задачу:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

И теперь, если вы хотите импортировать some_stuff из файла: Proj/Common/Common.py в ваш файл: Proj/Client/Client.py, просто так:

# in Proj/Client/Client.py
from Common.Common import some_stuff

И то же самое относится к Proj/Server, Также работает для setup.py процесса, тот же вопрос, обсуждаемый здесь , надеюсь, это поможет!

6 голосов
/ 07 января 2014

Делать относительный импорт абсолютно нормально!Вот что делает маленький я:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py
4 голосов
/ 22 сентября 2011

Метод импорта по умолчанию уже "относительный" из PYTHONPATH.PYTHONPATH по умолчанию для некоторых системных библиотек вместе с папкой исходного исходного файла.Если вы запускаете с -m для запуска модуля, текущий каталог добавляется в PYTHONPATH.Поэтому, если точка входа вашей программы находится внутри Proj, то использование import Common.Common должно работать как внутри Server.py, так и Client.py.

Не выполнять относительный импортЭто не сработает так, как вы хотите.

...