#python #python-3.x #namespaces #python-import
#python #python-3.x #пространства имен #python-импорт
Вопрос:
Я хочу использовать простое понимание списка для установки __all__
для модулей в моем пакете. Я замечаю, что когда я импортирую что-то из одного из своих собственных модулей, в пространство имен добавляется имя модуля, а не только то, что я импортирую. Это не то же самое, что при импорте встроенных или сторонних пакетов.
- foo
- __init__.py
- bar.py
- baz.py
__init__.py
import os as _os
from numpy.random import randint as _randint
import foo.bar as _bar
from foo.baz import foobar
__all__ = [x for x in globals() if not x.startswith('_')]
Я ожидаю:
>>> import foo
>>> foo.__all__
['foobar']
Но я получаю:
>>> import foo
>>> foo.__all__
['bar', 'baz', 'foobar']
Я знаю, что мог бы расширить свое понимание списка для __all__
фильтрации, ModuleType
но мне интересно, почему поведение отличается для моих собственных модулей. Мне бы очень хотелось иметь возможность использовать начальное подчеркивание для обработки этого, как я могу с другими пакетами. Я также пытался использовать dir()
, locals()
, и vars()
вместо globals()
, но результат тот же.
Обновить
Из любопытства я также импортировал foobar
bar.py
и распечатал globals()
и 'bar'
не был включен. Итак, похоже, что мои модули добавляются только в пространство имен внутри __init__.py
файлов?
Комментарии:
1. Имейте в виду, что подмодули по своей сути являются атрибутами своих родительских модулей. Например,
concurrent.futures
буквально является.futures
атрибутомconcurrent
. В вашем случаеfoo
содержитbaz
, потому что последнее есть на самом делеfoo.baz
.
Ответ №1:
Все благодарности @MisterMiyagi в комментариях.
Я только подтвержду это цитатой из официальной документации 5.4.2. Submodules:
Когда подмодуль загружается с использованием любого механизма […] в пространстве имен родительского модуля помещается привязка к объекту подмодуля.
Например, в вашем случае, если в пакете foo
есть подмодуль bar
, после импорта foo.bar
у foo
него будет атрибут bar
, который привязан к подмодулю foo.bar
.