Правильные способы установки пути моего приложения в Python - PullRequest
2 голосов
/ 15 февраля 2020

У меня вопрос о том, как правильно создать путь в Python (Python 3.x).

Я разработал небольшое приложение для очистки в Python со следующей структурой каталогов.

root
├── Dockerfile
├── README.md
├── tox.ini 
├── src
│   └── myapp
│       ├── __init__.py
│       ├── do_something.py
│       └── do_something_else.py
└── tests
    ├── __init__.py
    ├──  test_do_something.py
    └──  test_do_something_else.py

Когда я хочу запустить свой код, я могу go в каталог sr c и делать с python do_something.py Но, поскольку do_something.py имеет оператор импорта из do_something_else.py, он выдает ошибку:

Traceback (most recent call last):
  File "src/myapp/do_something.py", line 1, in <module>
    from src.myapp.do_something_else import do_it
ModuleNotFoundError: No module named 'src'

Итак, в конце концов я решил использовать следующую команду для указания пути python: PYTHONPATH=../../ python do_something.py, чтобы убедиться, что путь виден.

Но, Как лучше всего указать путь, чтобы мое приложение могло работать? Я хочу знать это, потому что когда я запускаю pytest через tox, каталог, в котором я буду запускать команду tox, будет находиться в root, так что tox.ini будет виден пакетом tox. Если я это сделаю, то, скорее всего, столкнусь с подобной проблемой из-за неправильно установленного пути Python.

Вопросы, которые я хочу задать конкретно:

  1. где следует Я запускаю свой основной код при создании своего собственного проекта, как это? root как python src/myapp/do_something.py? Или go в каталог src / myapp и запускать как python do_something.py?
  2. один раз, каталог, в котором я должен выполнить свою программу, определен, как правильно импортировать модули из другого файла py? Можно ли использовать from src.myapp.do_something_else import do_it (это означает, что я должен добавить путь из каталога sr c)? Или другой способ импорта?
  3. Каким образом мой Python может распознать путь? Я знаю, что есть несколько способов сделать пропуск доступным, как показано ниже:

    a. напишите export PYTHONPATH=<path_of_my_choice>:$PYTHONPATH, чтобы временно сделать путь доступным, или напишите эту строку в моем .bashr c, чтобы сделать его постоянным (но трудно воспроизвести, когда я хочу автоматизировать создание среды Python с помощью ansible или других средств автоматизации )

    б. напишите import sys; sys.path.append(<root>), чтобы root был доступным путем

    c. используйте пакет pytest-pythonpath (но на самом деле это не обобщенный c ответ)

Большое спасибо за ваш вклад!

мое окружение

OS: MacOS and Amazon Linux 2
Python Version: 3.7
Dependency in Python: pytest, tox

Ответы [ 2 ]

1 голос
/ 15 февраля 2020

Я бы предложил использовать setup.py, чтобы сделать этот пакет python. Затем вы можете установить его в режиме разработки python setup.py develop. Таким образом, он будет доступен в вашей среде python без указания PYTHONPATH.

Для тестирования вы можете просто установить пакет python setup.py install.

Надеюсь, это поможет.

0 голосов
/ 15 февраля 2020

Два простых шага должны сделать это. Python эксперты могут прокомментировать, если это хороший способ сделать это (особенно если следовать заключительной осторожности, поднятой в конце этого поста).

Я бы сделал это, как показано ниже.

Сначала я бы поместил "__init__.py" в root, чтобы иерархия выглядела так, как показано ниже. Таким образом, python будет рассматривать папку как пакет.

root
├── Dockerfile
├── README.md
├── tox.ini 
├── __init__.py
├── src
│   └── myapp
│       ├── __init__.py
│       ├── do_something.py
│       └── do_something_else.py
└── tests
    ├── __init__.py
    ├──  test_do_something.py
    └──  test_do_something_else.py

Тогда в "do_something.py" я бы добавил эти строки вверху. Во второй строке укажите полный путь к каталогу "root".

import sys
sys.path += ['/home/SomeUserName/SomeFolderPath/root']
from  src.myapp.do_something_else import do_it

Обратите внимание, что вторая строка существенно изменит sys.path, добавив путь к папке root (I угадайте, пока переводчик не выйдет). Если это не то, что вы можете себе позволить, то извините.

...