以下是我公司“foo.com”使用的各种Python软件包:
com.foo.bar.web
com.foo.bar.lib
com.foo.zig.web
com.foo.zig.lib
com.foo.zig.lib.lib1
com.foo.zig.lib.lib2
以下是将源存储在磁盘上的传统方法:
pysrc/
com/
foo/
bar/
web/
lib/
zig/
web/
lib/
lib1/
lib2/
PYTHONPATH=pysrc
但是出于组织目的(不同的团队,不同的版本控制等),我们希望将它们存储如下:
bar/
pysrc/
com/
foo/
bar/
web/
lib/
zig/
pysrc/
com/
foo/
zig/
web/
lib/
lib1/
lib2/
PYTHONPATH=bar/pysrc:zig/pysrc
问题是:
第二种组织方法是否存在任何问题?
例如,如果我们import com.foo
,Python会在哪里寻找__init__.py
?
符号链接这些目录是否有意义? e.g:
pysrc/
com/
foo/
bar/ -> symlink to /bar/pysrc/com/foo/
zig/ -> symlink to /zig/pysrc/com/foo/
欢迎任何一般代码组织建议。
答案 0 :(得分:4)
Python将按顺序通过sys.path(包括PYTHONPATH,然后是一些),在每个中查找一个com.foo包。它找到的第一个,它将用于排除其他人,不像Perl或Java有效地将包名称空间合并在一起。您可以对__path__
执行一些更改此行为的操作,但“首次匹配获胜”是Python开箱即用的行为。
只要您将所有com.foo.bar完全保留在bar /并且所有com.foo.zig完全保存在zig /中,您就不应该对第二个布局有任何问题。
答案 1 :(得分:3)
通过PEP 420 page阅读,看起来您可以将以下__init__.py
添加到共享包中:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
所以你的目录结构如下(* -marked __init__.py
文件有上面的代码):
myroot/
├── bar
│ └── pysrc
│ └── com
│ ├── ****__init__.py****
│ └── foo
│ ├── ****__init__.py****
│ └── bar
│ ├── __init__.py
│ ├── lib
│ │ ├── __init__.py
│ │ └── barlib.py
│ └── web
│ ├── __init__.py
│ ├── barweb.py
└── zig
└── pysrc
└── com
├── ****__init__.py****
└── foo
├── ****__init__.py****
└── zig
├── __init__.py
├── lib
│ ├── __init__.py
│ ├── lib1
│ │ ├── __init__.py
│ │ └── ziblib1.py
│ └── lib2
│ ├── __init__.py
│ └── ziblib2.py
└── web
├── __init__.py
├── zigweb.py
将python路径设置为指向com/
目录:
barPath=/myroot/bar/pysrc/
zigPath=/myroot/zig/pysrc/
export PYTHONPATH=$PYTHONPATH:$barPath:$zigPath
进行测试(我试过2.7.14和3.6.4):
from com.foo.bar.web.barweb import BarWeb
from com.foo.zig.web.zigweb import ZigWeb
b = BarWeb()
z = ZigWeb()
没有__init__.py
代码产生:
ImportError: No module named zig.web.zigweb