Я разрабатываю несколько проектов Python для нескольких клиентов одновременно.Упрощенная версия структуры папок моего проекта выглядит примерно так:
/path/
to/
projects/
cust1/
proj1/
pack1/
__init__.py
mod1.py
proj2/
pack2/
__init__.py
mod2.py
cust2/
proj3/
pack3/
__init__.py
mod3.py
Когда я, например, хочу использовать функциональность с proj1
, я расширяю sys.path
на /path/to/projects/cust1/proj1
(например, установив PYTHONPATH
или добавив файл .pth
в папку site_packages
или даже изменив sys.path
напрямую), а затем импортируйте модуль следующим образом:
>>> from pack1.mod1 import something
Когда я работаю над большим количеством проектов, бывает так, что разныепроекты имеют идентичные имена пакетов:
/path/
to/
projects/
cust3/
proj4/
pack1/ <-- same package name as in cust1/proj1 above
__init__.py
mod4.py
Если я теперь просто увеличу sys.path
на /path/to/projects/cust3/proj4
, я все еще могу импортировать из proj1
, но не из proj4
:
>>> from pack1.mod1 import something
>>> from pack1.mod4 import something_else
ImportError: No module named mod4
Я думаю, что причина, по которой второй импорт завершается неудачно, заключается в том, что Python ищет только первую папку в sys.path
, где он находит пакет pack1
и сдается, если он не находит там модуль mod4
.Я спрашивал об этом в предыдущем вопросе, см. импорт модулей Python с тем же именем , но внутренние детали мне все еще неясны.
В любом случае, очевидное решение состоит в том, чтобы добавитьеще один уровень квалификации пространства имен, превратив каталоги проектов в суперпакеты: добавьте __init__.py
файлы в каждую папку proj*
и удалите эти папки из строк, на которые расширен sys.path
, например,
$ export PYTHONPATH=/path/to/projects/cust1:/path/to/projects/cust3
$ touch /path/to/projects/cust1/proj1/__init__.py
$ touch /path/to/projects/cust3/proj4/__init__.py
$ python
>>> from proj1.pack1.mod1 import something
>>> from proj4.pack1.mod4 import something_else
сейчасЯ сталкиваюсь с ситуацией, когда разные проекты для разных клиентов имеют одно и то же имя, например
/path/
to/
projects/
cust3/
proj1/ <-- same project name as for cust1 above
__init__.py
pack4/
__init__.py
mod4.py
Попытка импорта из mod4
больше не работает по той же причине, что и раньше:
>>> from proj1.pack4.mod4 import yet_something_else
ImportError: No module named pack4.mod4
Следуя тому же подходу, который решал эту проблему ранее, я бы добавил еще один слой пакета / пространства имен и превратил бы папки клиента в супер-супер-пакеты.
Однако это противоречит другим требованиям, предъявляемым к моему проекту.структура папок, например
- структура разработки / выпуска для поддержки нескольких строк кода
- другие виды исходного кода, такие как, например, JavaScript, SQL и т. Д.
- другие файлы, помимо исходных файлов, например, документы или данные.
Менее упрощенный, более реальный-world описание некоторых папок проекта выглядит следующим образом:
/path/
to/
projects/
cust1/
proj1/
Development/
code/
javascript/
...
python/
pack1/
__init__.py
mod1.py
doc/
...
Release/
...
proj2/
Development/
code/
python/
pack2/
__init__.py
mod2.py
Я не понимаю, как я могу удовлетворить требования, которые интерпретатор Python предъявляет к структуре папок и к тем, которые у меня есть одновременно.Возможно, я мог бы создать дополнительную структуру папок с некоторыми символическими ссылками и использовать ее в sys.path
, но, глядя на усилия, которые я уже делаю, у меня возникает ощущение, что во всем моем подходе что-то в корне не так.Что касается sidenote, мне также трудно поверить, что python действительно ограничивает меня в выборе имен папок с исходным кодом, как это происходит в случае, изображенном.
Как я могу настроить свой проектпапки и sys.path
, чтобы я мог согласованно импортировать из всех проектов, если есть проекты и пакеты с одинаковыми именами?