Разделить исходный код Python на отдельные каталоги? - PullRequest
4 голосов
/ 18 июня 2010

Вот несколько различных пакетов Python, которые использует моя компания "foo.com":

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/

Любые общие организационные предложения по коду приветствуются.

Ответы [ 2 ]

4 голосов
/ 19 июня 2010

Python будет проходить через sys.path по порядку (который включает в себя PYTHONPATH, а затем некоторые из них), ища пакет com.foo в каждом.Первый, который он находит, он будет использовать для исключения других, в отличие от Perl или Java, которые эффективно объединяют пространства имен пакетов.Есть вещи, которые вы можете сделать для __path__, которые изменяют это поведение, но «первое совпадение выигрывает» - это то, как Python ведет себя «из коробки».

Пока вы полностью сохраняете весь com.foo.bar вbar / и весь com.foo.zig полностью в zig /, у вас не должно возникнуть проблем со вторым макетом.

3 голосов
/ 16 февраля 2018

Читая страницу PEP 420 , похоже, что вы можете добавить следующие __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
...