为什么即使没有显式导入子模块名称也可以在 __init__.py 中访问?
Why can sub-module names be accessed in __init__.py even without explicitly importing them?
问题:
pkg/
__init__.py
sub1.py
sub2.py
$ cat pkg/__init__.py
from .sub2 import *
print("init", dir())
$ cat pkg/sub1.py
from .sub2 import *
print("sub1", dir())
$ cat pkg/sub2.py
def spam():
...
$ python -c "import pkg"
init [... 'spam', 'sub2']
$ python -c "import pkg.sub1"
init [... 'spam', 'sub2']
sub1 [... 'spam']
请注意 sub2
是如何在 pkg
的命名空间中的,尽管我实际上并没有导入它。我希望只导入 sub2
中的名称。为什么不是这样呢?我看到它与导入包和导入模块有关,因为:
$ python -c "import pkg.__init__"
init [... 'spam', 'sub2']
init [... 'spam']
好像也很迷惑mypy
;我编辑 __init__.py
以显式访问 sub2
:
$ cat pkg/__init__.py
from .sub2 import *
print(sub2)
然后 运行 mypy pkg
给出:
pkg/__init__.py:2: error: Name "sub2" is not defined
Found 1 error in 1 file (checked 3 source files)
为什么会这样?这是记录的功能吗?我应该注意到这个“特性”在 Cpython 源代码中使用;例如,检查 Lib/asyncio/__init__.py
.
这有点像子模块的怪癖,但这是documented behavior:
When a submodule is loaded using any mechanism (e.g. importlib
APIs,
the import
or import-from
statements, or built-in __import__()
) a
binding is placed in the parent module’s namespace to the submodule
object. For example, if package spam
has a submodule foo
, after
importing spam.foo
, spam
will have an attribute foo
which is bound to
the submodule.
...
Given Python’s familiar name binding rules this might seem surprising,
but it’s actually a fundamental feature of the import system. The
invariant holding is that if you have sys.modules['spam']
and
sys.modules['spam.foo']
(as you would after the above import), the
latter must appear as the foo attribute of the former.
问题:
pkg/
__init__.py
sub1.py
sub2.py
$ cat pkg/__init__.py
from .sub2 import *
print("init", dir())
$ cat pkg/sub1.py
from .sub2 import *
print("sub1", dir())
$ cat pkg/sub2.py
def spam():
...
$ python -c "import pkg"
init [... 'spam', 'sub2']
$ python -c "import pkg.sub1"
init [... 'spam', 'sub2']
sub1 [... 'spam']
请注意 sub2
是如何在 pkg
的命名空间中的,尽管我实际上并没有导入它。我希望只导入 sub2
中的名称。为什么不是这样呢?我看到它与导入包和导入模块有关,因为:
$ python -c "import pkg.__init__"
init [... 'spam', 'sub2']
init [... 'spam']
好像也很迷惑mypy
;我编辑 __init__.py
以显式访问 sub2
:
$ cat pkg/__init__.py
from .sub2 import *
print(sub2)
然后 运行 mypy pkg
给出:
pkg/__init__.py:2: error: Name "sub2" is not defined
Found 1 error in 1 file (checked 3 source files)
为什么会这样?这是记录的功能吗?我应该注意到这个“特性”在 Cpython 源代码中使用;例如,检查 Lib/asyncio/__init__.py
.
这有点像子模块的怪癖,但这是documented behavior:
When a submodule is loaded using any mechanism (e.g.
importlib
APIs, theimport
orimport-from
statements, or built-in__import__()
) a binding is placed in the parent module’s namespace to the submodule object. For example, if packagespam
has a submodulefoo
, after importingspam.foo
,spam
will have an attributefoo
which is bound to the submodule.
...
Given Python’s familiar name binding rules this might seem surprising, but it’s actually a fundamental feature of the import system. The invariant holding is that if you have
sys.modules['spam']
andsys.modules['spam.foo']
(as you would after the above import), the latter must appear as the foo attribute of the former.