Нужен ли мне PYTHONPATH - PullRequest
       18

Нужен ли мне PYTHONPATH

1 голос
/ 12 апреля 2019

Есть много похожих вопросов о PYTHONPATH и импорте, но я не нашел именно то, что мне нужно.

У меня есть git-репозиторий, который содержит несколько скриптов-помощников python.Сценарии естественно организованы в несколько пакетов.Что-то вроде:

scripts/main.py
scripts/other_main.py
scripts/__init__.py
a/foo.py
a/bar.py
a/__init__py
b/foo.py
b/bar.py
b/__init__.py
__init__.py

scripts зависит от a и b.Я использую абсолютный импорт во всех модулях.Я бегу python3 scripts/main.py.Все работает до тех пор, пока я установил PYTHONPATH в корневой каталог моего проекта.

Однако я бы хотел, чтобы пользователям не пришлось настраивать переменную среды.

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

РЕДАКТИРОВАТЬ: кажется, будет работать, если я удаляю верхний уровень __init__.py

1 Ответ

2 голосов
/ 12 апреля 2019

Во-первых, вы правы в том, что я не думаю, что вам нужен верхний уровень __init__.py. Однако удаление его не решает никакой ошибки импорта.

Вам не нужно устанавливать PYTHONPATH, и я могу придумать несколько альтернатив:

  1. Использование виртуальной среды (https://virtualenv.pypa.io/en/latest/). Это также потребует от вас упаковки вашего кода в устанавливаемый пакет (https://packaging.python.org/).) Я не буду объяснять эту опцию далее, поскольку она не является прямой связанных с вашим вопросом.

  2. Переместите свои модули в каталог scripts. Python автоматически добавляет каталог скрипта в путь Python.

  3. Измените переменную sys.path в ваших скриптах, чтобы они могли найти ваши локальные модули.

Второй вариант самый простой.

Третий вариант потребует от вас добавления некоторого кода Python в начало ваших скриптов, выше вашего обычного импорта. В вашем main.py это будет выглядеть так:

#!/usr/bin/env python
import os.path, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))

import a
import b

Что это делает:

  • Возьмите имя файла сценария

  • рассчитать родительский каталог каталога скрипта

  • Добавить этот каталог к ​​sys.path

  • Затем выполните обычный импорт ваших модулей

...