PYTHONPATH против sys.path

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

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

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

В script.py нам нужно сделать import package.lib. Когда пакет установлен в site-packages, 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 или оба варианта подходят?


person gaefan    schedule 12.12.2009    source источник
comment
Кажется, что голоса и ответы разделены довольно равномерно с очень небольшим уклоном в сторону использования PYTHON_PATH, хотя это может быть шум выборки или непреднамеренное смещение вопроса.   -  person AJP    schedule 31.01.2017
comment
О разнице между PATH и sys.path (и косвенно PYTHONPATH) см. также stackoverflow.com/questions/25344841/sys- путь-против-пути   -  person tripleee    schedule 10.11.2020


Ответы (6)


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

person Ned Batchelder    schedule 12.12.2009
comment
Можете ли вы дать немного больше разъяснений по этому поводу? Даже если вы поддерживаете среду conda/virtualenv, как это поместит каталог верхнего уровня на ваш путь к Python? - person compguy24; 18.03.2019

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

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

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

person bobince    schedule 12.12.2009
comment
Проблема с site.addsitedir заключается в том, что он выполняет append по отношению к sys.path, а это означает, что установленный пакет будет иметь приоритет над локальным пакетом в разработке (и может последовать выдергивание волос). sys.path.insert(0... необходимо преодолеть это. - person Eli Bendersky; 08.04.2013
comment
@EliBendersky: должно быть sys.path.insert(1. stackoverflow.com/q/10095037/125507 - person endolith; 14.06.2014

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

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

person sateesh    schedule 12.12.2009

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

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

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

person unutbu    schedule 12.12.2009

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

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

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

person shylent    schedule 12.12.2009

Ни взлом PYTHONPATH, ни sys.path не является хорошей идеей по вышеупомянутым причинам. А для привязки текущего проекта к папке site-packages на самом деле есть лучший способ, чем python setup.py develop, как объяснено здесь:

pip install --editable path/to/project

Если у вас еще нет файла setup.py в корневой папке вашего проекта, этого достаточно для начала:

from setuptools import setup
setup('project')
person Peter    schedule 03.01.2020