PYTHONPATH проти sys.path


92

Ми з іншим розробником не погоджуємось, чи слід використовувати PYTHONPATH або sys.path, щоб дозволити Python знаходити пакет Python в каталозі користувача (наприклад, розробці).

У нас є проект Python із типовою структурою каталогів:

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

У script.py нам потрібно це зробити import package.lib. Коли пакет інстальовано в site-пакети, 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, або це нормально?


4
Здається, голоси та відповіді розподіляються досить рівномірно, з дуже незначним нахилом до використання PYTHON_PATH, хоча це може бути шум вибірки або ненавмисне упередження з питання.
AJP

Відповіді:


42

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


10
Чи можете ви запропонувати трохи більше роз’яснень щодо цього? Навіть якщо ви виставляєте середовище conda / virtualenv, як би це поставило каталог верхнього рівня на ваш шлях python?
compguy24

38

Я ненавиджу ПІФОНПАТ. Мені здається крихким та надокучливим встановлювати для кожного користувача (особливо для користувачів демонів) і відстежувати, як папки проекту рухаються. Я набагато краще б встановив sys.pathсценарії виклику для окремих проектів.

Однак sys.path.appendце не спосіб це зробити. Ви можете легко отримати дублікати, і це не сортує .pthфайли. Краще (і більш читабельним): site.addsitedir.

І script.pyзазвичай це не найкраще місце для цього, оскільки воно знаходиться всередині пакету, який ви хочете зробити доступним на шляху. Бібліотечні модулі, звичайно, не повинні стосуватися sys.pathсамих себе. Замість цього у вас зазвичай буде скрипт hashbanged поза пакетом, який ви використовуєте для створення екземпляра та запуску програми, і саме в цьому тривіальному сценарії обгортки ви б sys.pathвказали деталі розгортання, наприклад -frobbing.


16
Проблема в site.addsitedirтому , що він робить appendON sys.path, а це означає , що встановлений пакет матиме пріоритет над місцевим пакетом в розвитку (і тягання за волосся можуть наступити). sys.path.insert(0...потрібно, щоб подолати це.
Елі Бендерський

5
@EliBendersky: повинно бути sys.path.insert(1. stackoverflow.com/q/10095037/125507
ендоліт

12

Загалом, я вважав би встановлення змінної середовища (наприклад, PYTHONPATH) поганою практикою. Хоча це може бути добре для одноразової налагодження, але використовувати це як
звичайну практику може бути не найкращою ідеєю.

Використання змінної середовища призводить до таких ситуацій, як "це працює для мене", коли хтось
інший повідомляє про проблеми в основі коду. Також можна провести таку ж практику з тестовим середовищем, що призведе до таких ситуацій, як тести, які працюють нормально для певного розробника, але, ймовірно, не вдаються, коли хтось запускає тести.


6

Поряд з багатьма іншими причинами, про які вже згадувалося, ви також можете зазначити, що це жорстке кодування

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 вручну, якщо він використовується поза пакетами сайту. .


3

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

pip install --editable path/to/project

Якщо у вас ще немає файлу setup.py у кореневій папці вашого проекту, для початку це досить:

from setuptools import setup
setup('project')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.