PYTHONPATH против sys.path

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

У нас есть проект 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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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