Отличается ли порядок поиска для пакетов пространства имен Python от обычных пакетов? - PullRequest
0 голосов
/ 29 апреля 2020

Из того, что я понял из чтения PEP 420 , начиная с python3 .3 пустых __init__.py файлов, больше нет необходимости превращать каталоги в python пакеты. если __init__.py опущен, пакет считается пакетом пространства имен. Кроме того, пакеты пространства имен должны вести себя так же, как и обычные пакеты. Из PEP

Пакет пространства имен принципиально не отличается от обычного пакета. Это просто другой способ создания пакетов. После создания пакета пространства имен между ним и обычным пакетом нет никакой функциональной разницы.

Однако порядок, в котором ищутся пакеты, кажется, совершенно различен для двух типов пакетов. Для обычных пакетов текущий рабочий каталог, кажется, ищется перед установочными каталогами, в то время как для пакетов пространства имен обратное верно. Это предполагаемое поведение? Кажется, я не могу найти упоминаний об этом в PEP или в других источниках.

Пример

Например, попробуйте выполнить следующее из пустой директории. Он импортирует установленный модуль pytest.

$ tree
.

0 directories, 0 files

$ python3.7
>>> import pytest
>>> print(pytest.__file__)
/opt/lib/python3.7/site-packages/pytest.py

Теперь создайте файл с именем pytest.py в каталоге и снова запустите его. Он импортирует ожидаемый локальный пакет.

$ tree
.
`-- pytest.py

0 directories, 1 file

$ python3.7
>>> import pytest
>>> print(pytest.__file__)
/home/cnoor/ns_package_test/pytest.py

Теперь удалите файл pytest.py и создайте каталог с именем pytest. Импортирует установленный пакет вместо локального. Почему?

$ tree
.
`-- pytest/

1 directory, 0 files

$ python3.7
>>> import pytest
>>> print(pytest.__file__)
/opt/lib/python3.7/site-packages/pytest.py

теперь попробуйте добавить пустой файл __init__.py в каталог pytest. Он снова импортирует локальный.

$ tree
.
`-- pytest/
    `-- __init__.py

1 directory, 1 file

$ python3.7
>>> import pytest
>>> print(pytest.__file__)
/home/cnoor/ns_package_test/pytest/__init__.py

Может кто-нибудь объяснить, что происходит? Я знаю, что импорт пустых пакетов - не самая полезная вещь в мире, но ситуация применима, даже если в пакете есть субмодули или субпакеты.

...