5

以下是我的公司“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

对这些目录进行符号链接有意义吗?例如:

pysrc/
  com/
    foo/
      bar/ -> symlink to /bar/pysrc/com/foo/
      zig/ -> symlink to /zig/pysrc/com/foo/

欢迎任何一般的代码组织建议。

4

2 回答 2

4

Python 将依次遍历 sys.path(其中包括 PYTHONPATH 和一些),在每个中寻找一个 com.foo 包。它找到的第一个,它将用于排除其他人,不像 Perl 或 Java,它有效地将包名称空间合并在一起。你可以做一些事情来__path__改变这种行为,但是“第一场比赛获胜”是 Python 开箱即用的行为方式。

只要您将所有 com.foo.bar 完全保留在 bar/ 中,并将所有 com.foo.zig 完全保留在 zig/ 中,您就不应该对第二个布局有任何问题。

于 2010-06-18T20:00:49.067 回答
3

通读PEP 420 page,看起来您可以将以下内容添加__init__.py到共享包中:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

所以你的目录结构如下(*标记的__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
于 2018-02-16T19:23:08.837 回答