Импорт из относительного пути в Python


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

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

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

5 63

5 ответов:

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

с PEP8:

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

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

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

редактировать ноябрь 2014 (3 года спустя):

Python 2.6 и 3.x поддерживает правильный относительный импорт, где вы можете избежать каких-либо хакерских действий. С помощью этого метода, вы знаете, что вы получаете относительные импорт, а не абсолютное импорт. Этот.' .- значит, иди в директорию надо мной:

from ..Common import Common

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

python -m Proj

оригинальный hacky way

этот метод по-прежнему широко используется в некоторых ситуациях, когда вы на самом деле никогда не "устанавливаете" свой пакет. Например, он популярен среди пользователей Django.

вы можете добавить Common/ в свою систему.путь (список путей python смотрит на импорт вещей):

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

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

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

объединение с командой linux ln, мы можем сделать вещь много simper:

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, работает на

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

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

выполнение относительного импорта абсолютно нормально! Вот что делает маленький ' ol me:

#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