Как правильно импортировать подпакеты в python? - PullRequest
1 голос
/ 02 октября 2019

У меня ошибка import, которую я не понимаю. Я сделал минимальный пример ниже, небольшой пакет пространства имен с именем p_parent, который не содержит файл __init__.py, но содержит другой подпакет с именем c_child

. Вот полное древовидность:

p_parent
├── c_child
│   ├── c_main.py
│   └── __init__.py
└── p_main.py

c_main.py и p_main.py почти ничего не содержат. p_parent/c_child/__init__.py содержит только импорт.

Вот сценарий оболочки, который перестраивает это:

mkdir p_parent
mkdir p_parent/c_child
echo '#!/usr/bin/env python3\n\nc_value = 4\n' > p_parent/c_child/c_main.py
echo '#!/usr/bin/env python3\n\np_value = 4\n' > p_parent/p_main.py
echo '#!/usr/bin/env python3\n\nimport p_parent.c_child.c_main as c\n' > p_parent/c_child/__init__.py

Когда содержимое файла __init__.py равно import p_parent.c_child.c_main as c Я получаю ошибку Iне понимаю, когда я пытаюсь импортировать подмодуль:

>>> import p_parent.c_child
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/C/autools/release/2019.09/scade/package/p_parent/c_child/__init__.py", line 3, in <module>
    import p_parent.c_child.c_main as c
AttributeError: module 'p_parent' has no attribute 'c_child'

Но, что говорит мне, что я пропустил что-то действительно важное, так это то, что когда содержимое файла __init__.py только import p_parent.c_child.c_main, все работаеткак и ожидалось (за исключением того, что у меня более длинные имена)

>>> import p_parent.c_child
>>> p_parent.c_child.c_main
<module 'p_parent.c_child.c_main' from '/<snip>/p_parent/c_child/c_main.py'>
>>> p_parent.c_child.c_main.c_value
4

с from p_parent.c_child.c_main * это работает как-то, но я бы предпочел этого избежать:

>>> import p_parent.c_child
>>> p_parent.c_child.c_value
4

В чем здесь логика? Почему ошибка настолько неинтуитивна?

используется python3.6

...