我试图使用importlib.util
我最终只导入了importlib
$ python3.6
>>> import importlib
>>> importlib.util
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
因为我知道有importlib.util
我然后导入了完整的模块名称
>>> import importlib.util
>>> importlib.util
<module 'importlib.util' from '/Users/alexlord/.virtualenvs/python3.6/lib/python3.6/importlib/util.py'>
这看起来像一个动态模块,只有在您直接导入它时才会加载。
这让我感到惊讶,如何发现这些动态加载的模块?是否有一种编程方式来发现它们,或者我只需要枚举源代码?
答案 0 :(得分:0)
默认情况下,包不会导入模块(或子包)。
所以:
import importlib
不会导入模块util。
但是开发人员可以选择为你做这件事。
例如:
>>> import os
>>>
>>> os.path.pathsep
':'
要了解有关模块和包的所有信息,可以使用excellent tutorial。
注意:您还可以使用“命名空间包”。有关详细信息,请参阅PEP 420。
修改强>
要查找子模块,您可以使用pkg_resources.resource_listdir()
:
import pkg_resources
l = [m for m in pkg_resources.resource_listdir('importlib', '.')
if m.endswith('.py') and not m.startswith('_')]
你得到:
['abc.py', 'machinery.py', 'util.py']
请参阅文档中的Basic Resource Access。
编辑2
发现子包或子模块的另一种方法是使用pkgutil.walk_packages。这可能是最好的解决方案。
例如:
import pkgutil
import importlib
for i in pkgutil.walk_packages(importlib.__path__):
print(i)
你得到:
(FileFinder('/var/containers/Bundle/Application/84CF9501-45D6-43E0-9319-886F5DE85176/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/importlib'), '_bootstrap', False)
(FileFinder('/var/containers/Bundle/Application/84CF9501-45D6-43E0-9319-886F5DE85176/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/importlib'), '_bootstrap_external', False)
(FileFinder('/var/containers/Bundle/Application/84CF9501-45D6-43E0-9319-886F5DE85176/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/importlib'), 'abc', False)
(FileFinder('/var/containers/Bundle/Application/84CF9501-45D6-43E0-9319-886F5DE85176/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/importlib'), 'machinery', False)
(FileFinder('/var/containers/Bundle/Application/84CF9501-45D6-43E0-9319-886F5DE85176/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/importlib'), 'util', False)