带有子模块导入的命名空间
namespace with submodule imports
我想使用简单的列表理解来为我的包中的模块设置 __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
个文件中的命名空间?
在评论中感谢@MisterMiyagi。
我只会引用官方文档来证实这一点 5.4.2. Submodules:
When a submodule is loaded using any mechanism [...] a binding is placed in the parent module’s namespace to the submodule object.
例如,在您的情况下,如果包 foo
有一个子模块 bar
,在导入 foo.bar
之后,foo
将有一个属性 bar
绑定到子模块 foo.bar
.
我想使用简单的列表理解来为我的包中的模块设置 __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
个文件中的命名空间?
在评论中感谢@MisterMiyagi。
我只会引用官方文档来证实这一点 5.4.2. Submodules:
When a submodule is loaded using any mechanism [...] a binding is placed in the parent module’s namespace to the submodule object.
例如,在您的情况下,如果包 foo
有一个子模块 bar
,在导入 foo.bar
之后,foo
将有一个属性 bar
绑定到子模块 foo.bar
.