#python #sys #python-venv #sys.path
#python #sys #python-venv #sys.path
Вопрос:
У меня есть каталог проекта, который выглядит следующим образом
/work
/venv
/project1
app.py
/package1
/package2
etc
где скрипт app.py управляет проектом, над которым я работаю. Когда я запускаю
python -m site
из /project1
каталога, я получаю, как и ожидалось
sys.path = [
'/work/project1',
плюс соответствующие /lib/pythonX.Y
пути. Однако при запуске app.py (из project1) этот импорт
from package1 import ...
сбой с ModuleNotFoundError, в то from .package1 import ...
время как работает нормально, поскольку он сообщает python для поиска каталога, который app.py находится внутри. Итак, я добавил это в начало app.py
import sys
print(sys.path)
и в результате получается
sys.path = [
'/work',
Вместо /work/project1
каталога, в котором выполняется поиск при импорте в app.py есть /work
. В чем причина этого несоответствия между python -m site
и print(sys.path)
и каков наилучший способ убедиться, что /work/project1
это всегда часть sys.path?
Я бы хотел избежать использования чего-то подобного site.addsitedir()
и, возможно, вместо этого использовать файл .pth. Из того, что я прочитал, хотя файл .pth принадлежит /lib/pythonX.Y/sitepackages
, но мне также нужно, чтобы это решение было независимым от системы, чтобы сотруднику, который клонирует /project1
из github, не нужно было добавлять свой собственный файл .pth.
Ответ №1:
Я не знаю, применимо ли это к вам, но я помог многим другим, указав, что делает наш магазин. Мы вообще не беспокоимся о пути при выполнении. Все, на что мы полагаемся, это то, что из начального местоположения скрипта мы знаем, где находятся все зависимости. Затем мы добавляем каталоги в sys.path, вычисляя их позиции относительно каталога, содержащего исходный скрипт, который всегда доступен.
Мы помещаем эту логику в файл с именем init.py
в том же каталоге, что и основной скрипт. Вот как это выглядит:
repoPath = os.path.dirname(__file__) "/../../Development/repo1"
sys.path.append(repoPath "/common/common-pyutil")
sys.path.append(repoPath "/common/common-pyutil/thirdparty")
а затем в основном скрипте сделайте import init
. У нас есть каталоги с множеством скриптов в них, и все они просто import init
исправляют свой sys.path, чтобы найти все наши служебные модули и тому подобное.