2009-12-12 6 views
62

Еще один разработчик и я не согласен с тем, следует ли использовать PYTHONPATH или sys.path, чтобы позволить Python находить пакет Python в каталоге пользователя (например, разработке).PYTHONPATH vs. sys.path

У нас есть проект Python с типичной структурой каталогов:

Project 
    setup.py 
    package 
     __init__.py 
     lib.py 
     script.py 

В script.py, нам нужно сделать import package.lib. Когда пакет устанавливается в сайтах-пакетах, script.py может найти package.lib.

При работе с каталогом пользователей, однако, что-то еще нужно сделать. Мое решение - установить PYTHONPATH для включения «~/Project». Другой разработчик хочет поставить эту строку кода в начале script.py:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

Так что Python может найти локальную копию package.lib.

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

Должны ли мы использовать PYTOHNPATH, sys.path, или это нормально?

+1

Кажется, что голоса и ответы разделены довольно равномерно с очень небольшим наклоном к использованию PYTHON_PATH, хотя это может быть шум выборки или непреднамеренное смещение вопроса. – AJP

ответ

37

Если единственная причина для изменения пути для разработчиков, работающих с их рабочим деревом, то вы должны использовать инструмент установки для настройки вашей среды для вас. virtualenv очень популярен, и если вы используете setuptools, вы можете просто запустить setup.py develop, чтобы установить установку рабочего дерева в текущей установке Python.

2

Я думаю, что в этом случае использование PYTHONPATH - лучшая вещь, главным образом потому, что она не вводит (сомнительный) ненужный код.

В конце концов, если вы об этом думаете, ваш пользователя не нуждается в том, что sys.path вещи, потому что ваш пакет будет установлен в сайте-пакеты, потому что вы будете использовать систему упаковки.

Если пользователь выбирает запуск из «локальной копии», как вы его называете, то я заметил, что обычной практикой является указание, что пакет необходимо добавить в PYTHONPATH вручную, если он используется снаружи сайтов-пакетов.

32

Ненавижу PYTHONPATH. Я нахожу это хрупким и раздражающим, чтобы установить для каждого пользователя (особенно для пользователей-демонов) и отслеживать движение по папкам проекта. Я бы предпочел установить sys.path в сценариях вызова для автономных проектов.

Однако sys.path.append не может это сделать. Вы можете легко получить дубликаты, и он не сортирует файлы .pth. Лучше (и более читаемый): site.addsitedir.

И script.py обычно не подходит для того, чтобы это сделать, так как это внутри пакет, который вы хотите сделать доступным на пути. Модули библиотеки, конечно же, не должны касаться sys.path. Вместо этого у вас обычно есть hashbanged-скрипт за пределами пакета, который вы используете для создания экземпляра и запуска приложения, и именно в этом тривиальном сценарии оболочки вы разместили данные о развертывании, такие как sys.path -frobbing.

+10

Проблема с 'site.addsitedir' заключается в том, что она« добавляет »на' sys.path', что означает, что установленный пакет будет иметь приоритет над локальным пакетом в разработке (и может произойти вытягивание волос). 'sys.path.insert (0 ...' необходимо для преодоления этого. –

+3

@EliBendersky: должно быть 'sys.path.insert (1'. http://stackoverflow.com/q/10095037/125507 – endolith

4

Наряду со многими другими причинами, упомянутых уже, можно также указать, что outh закодировав

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

является хрупким, поскольку он предполагает расположение script.py - он будет работать, только если сценарий .py находится в Project/package. Он сломается, если пользователь решит переместить/скопировать/symlink script.py (почти) в другое место.

7

В общем, я бы рассмотрел настройку переменной окружения (например, PYTHONPATH) , чтобы быть плохой практикой. Хотя это может быть хорошо для одной отладки, но используя это как
, обычная практика может быть не очень хорошая идея.

Использование переменной окружения приводит к ситуациям типа «это работает для меня», когда какой-то
еще сообщает о проблемах в базе кода. Также можно было бы провести такую ​​же практику с тестовой средой , что привело бы к таким ситуациям, как тесты, отлично работающие для конкретного разработчика , но, вероятно, не удалось, когда кто-то запускает тесты.

Смежные вопросы