我正在为几个客户同时开发几个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/
__init__.py
mod4.py如果我现在简单地通过/path/to/projects/cust3/proj4扩展sys.path,我仍然可以从proj1导入,但不能从proj4导入:
>>> from pack1.mod1 import something
>>> from pack1.mod4 import something_else
ImportError: No module named mod4我认为第二次导入失败的原因是Python仅搜索sys.path中找到pack1包的第一个文件夹,如果它没有找到mod4模块,就放弃它。我在先前的问题中询问过这个问题,请参阅import python modules with the same name,但内部细节仍不清楚。
无论如何,显而易见的解决方案是通过将项目目录变为超级软件包来添加另一层名称空间限定:将__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/
__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中使用它,但是看看我已经做出的努力,我感觉我的整个方法存在根本性的错误。在旁注中,我也很难相信python真的限制了我对源代码文件夹名称的选择,正如它在所描述的情况下所做的那样。
如何设置我的项目文件夹和sys.path,以便能够以一致的方式从所有项目中导入,如果项目和程序包具有相同的名称?