Python 命名空间包可以分布在多个目录、zip 文件或自定义导入器中。如何正确地遍历命名空间包的所有可导入子模块?
Python 命名空间包可以分布在多个目录、zip 文件或自定义导入器中。如何正确地遍历命名空间包的所有可导入子模块?
all.py
的新子模块。import mynamespace.all
您将得到mynamespace
模块的对象。该对象包含命名空间中加载的所有模块,无论它们在何处加载,因为只有一个mynamespace
实例存在。
因此,在all.py
中加载命名空间中的所有软件包即可!
# all.py
from pkgutil import iter_modules
# import this module's namespace (= parent) package
pkg = __import__(__package__)
# iterate all modules in pkg's paths,
# prefixing the returned module names with namespace-dot,
# and import the modules by name
for m in iter_modules(pkg.__path__, __package__ + '.'):
__import__(m.name)
或者使用一行代码来保持all
模块为空,如果你关心这种事情的话:
# all.py
(lambda: [__import__(_.name) for _ in __import__('pkgutil').iter_modules(__import__(__package__).__path__, __package__ + '.')])() # noqa
从命名空间导入all
模块后,您实际上会收到一个完全填充的命名空间模块:
import mynamespace.all
mynamespace.mymodule1 # works
mynamespace.mymodule2 # works
...
from io.drivers import zip
通常比编写import io.drivers.zip
更方便,因为前者让您可以简单地引用模块而不是完整名称。
from modname import *
,这提供了一种将模块中的所有项目导入当前命名空间的简便方法;但是,应该谨慎使用此语句。*
导入是可怕的做法。虽然它在 Python 中是有效的,但除了少数特定情况外,它几乎总是一个坏主意。 - Daenyth