Python ссылается на подмодули из импорта корневого пакета - PullRequest
1 голос
/ 28 июня 2019

Проблема:

Предположим, у меня есть структура каталогов, такая как:

root/
    __init__.py
    foo.py
    dir1/
        __init__.py
        bar.py
        dir2/
            __init__.py
            baz.py

, где различные файлы Python содержат некоторую функцию с именем hello_world.

Я хочу написать что-то вроде:

import root
root.dir1.foo.hello_world()
root.dir1.dir2.baz.hello_world()

Конечно, когда я делаю это, я получаю ошибку AttributeError: module has no attribute. Это, я думаю, связано с «ловушкой __init__.py» в документах . Как мне манипулировать файлами инициализации так, чтобы я мог запустить приведенный выше код?

Предостережения

  • Я бы хотел избежать удаления файлов инициализации, поскольку они содержат параметр __all__, и это важно для моей программы.
  • Я также хотел бы избежать написания более чем одного оператора импорта в основной программе, поэтому решение, указанное здесь , не будет работать.
  • Я использую Python 3.6

Что я пробовал:

Я пытался обойти это, изменив файлы __init__.py в пакеты пространства имен ). К сожалению, это не похоже на работу. Например. добавление:

__path__ = __import__('pkgutil').extend_path(__path__, __name__)

для различных файлов инициализации ничего не меняет. Аналогично, установка атрибута __path__ напрямую не решает проблему. Например. в каждом файле инициализации установка __path__ = ['<string name of child dir>'] не устраняет ошибку.

Это немного загадочно для меня, поскольку __path__ должен сообщать python, где искать подмодули, а файлы инициализации должны запускаться последовательно, так почему же он не может выяснить, где что находится?

Примечания:

Эта проблема описана в документации здесь

1 Ответ

1 голос
/ 28 июня 2019

Одним из решений было поставить from . import * после определения свойства __all__ в каждом файле инициализации.Например, в init в dir1 положить:

__all__ = ['foo', 'dir2']
from . import *

Это решает вариант использования, но кажется, что это неправильный путь.Открой для лучших ответов.

...