Иерархия модуля python связана со структурой каталогов? - PullRequest
0 голосов
/ 02 мая 2020

Считайте, что это более усовершенствованная версия этого вопроса .

Кажется, структура модуля python привязана к фактическому каталогу, содержащему файлы. Хотя можно реэкспортировать другой модуль, используя __init__.py, это не изменяет фактическую иерархию модулей в качестве журнала, как это касается средства импорта.

Например:

some_dir
├ main.py
└ mod_a
  ├ __init__.py
  └ mod_b
    └ mod_c.py

mod_a/__init__.py:

from .mod_b import mod_c

mod_a/mod_b/mod_c.py:

def foo():
    print("Foo!")

В этом случае мы можем сделать это в main.py:

from mod_a import mod_c

mod_c.foo()

, но не это:

import mod_a.mod_c

mod_c.foo()

, который завершается с:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import mod_a.mod_c
ModuleNotFoundError: No module named 'mod_a.mod_c'

Так что init .py не может точно изменить иерархию модулей; И это самая близкая вещь к «изменению иерархии модулей» в python, о которой я знаю.

Итак, есть ли способ изменить иерархию модулей? Как в:

  • способ сделать import mod_a.mod_c допустимым оператором импорта?
  • способ смонтировать некоторый модуль python по произвольному пути к некоторому пути импорта, в общем ?

1 Ответ

0 голосов
/ 03 мая 2020

Это можно сделать, изменив __path__, pkgutil.extend_path или другими способами.

Согласно документации :

Атрибут пакета __path__ используется при импорте его подпакетов. В механизме импорта он работает почти так же, как sys.path, т.е. предоставляет список мест для поиска модулей во время импорта.

__path__ может быть изменено в __init__.py модуля для изменить, где система импорта ищет подмодули.

В данном случае, используя pkgutil.extend_path:

# mod_a/__init__.py
from pkgutil import extend_path

__path__ = extend_path(__path__, __name__ + '.mod_b')

или изменяя __path__ вручную:

# mod_a/__init__.py
__path__.append("(...)/some_dir/mod_a/mod_b")

где фактический путь к mod_b предпочтительно вычисляется из __file__.

Эти SO вопросы и ответы более подробно касаются использования __path__.

...