2015-12-06 2 views
0

Давайте это __init__.py в пакете Python3:Почему этот код, связанный с импортом, работает в __init__.py, но не в другом .py-файле?

from .mod1 import * 
from .mod2 import * 
from .mod3 import * 
__all__ = mod1.__all__ + mod2.__all__ + mod3.__all__ 

Код выглядит довольно просто и делает то, что, как ожидается: она импортирует из модулей mod1, mod2 и Mod3 все символы, которые эти модули клали в их __all__ список и то создается сводка всех трех списков __all__.

Я попытался запустить тот же код в модуле, то есть не в __init__.py. Он импортировал три модуля, но mod1, mod2 и mod3 были неопределенными переменными.

(Кстати, если вы запустите pylint на оригинальном __init__.py, вы получите эту ошибку тоже.)

То же самое утверждение from .mod1 import *mod1 создает объект при выполнении в __init__.py, но не создает его в другом месте. Зачем?

__init__.py - специальный файл, но до сих пор я думал, что его имя было особенным.

+0

Немного побочного вопроса, но: почему вы вообще это делаете? – jonrsharpe

+0

@jonrsharpe У меня есть логический симулятор схемы с библиотекой строительных блоков, определенных в нескольких файлах. Я хочу иметь возможность просто добавить новый файл с блоками, которые будут добавлены в библиотеку. Я нашел несколько рецептов, и теперь я тестирую их и изучаю. – VPfB

ответ

1

Согласно documentation, это ожидаемое поведение:

Когда подмодуль загружается с помощью какого-либо механизма (например, importlib API, то import или import-from заявления, или встроенный в __import__()) связывание помещают в пространство имен родительского модуля для объекта подмодуля. Например, если пакет spam имеет подмодуль foo, после импорта spam.foo, spam будет иметь атрибут foo, который привязан к подмодулю.

Другими словами, когда вы делаете from .whatever import somethingв модуле, вы волшебно получить атрибут whatever связанный к модулю. Естественно, вы можете получить доступ к собственным атрибутам модуля в пределах __init__.py, как если бы они были определены как переменные. Когда вы находитесь в другом модуле, вы не можете этого сделать. В этом смысле __init__.py действительно особенный.

+0

Я должен прочитать ваш ответ несколько раз. О, надеюсь, я наконец получил это. Если x и x.y импортированы, Python «делает ссылку» от x до y. Только x является родительским элементом y, независимо от того, кто его импортирует. – VPfB

+0

Да, это точка. –

Смежные вопросы