Я разрабатываю несколько проектов 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 и т.д.
- другие файлы, кроме исходных файлов, например, документов или данных.
Менее упрощенное, более реальное изображение некоторых папок проекта выглядит следующим образом:
/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
, чтобы я мог последовательно импортировать из всех проектов, если есть проекты и пакеты с одинаковыми именами?