2017-05-24 106 views
-1

我尝试使用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我再导入完整的模块名称

这看起来像一个动态模块,只有在直接导入它时才会加载。

这让我想不到,如何发现这些动态加载的模块?有没有一种编程方式来发现它们,或者我只需要枚举源代码?

+1

'importlib'是一个包。包的子模块只有在显式导入它们的时候才会被加载(尽管显式导入可能在某处你永远不会看到,取决于包和子模块)。 – user2357112

回答

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的文件中。

EDIT 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) 
+1

'os.path'是一个不好的例子,因为'os'不是实际上是一个包。 'os'用'sys.modules'直接混淆,以使'os.path'的行为有点像包子模块。 – user2357112

+0

那么,我不知道这个细节。标准库中的任何其他示例? –

+0

我觉得'os'是标准库中唯一能够完成它的奇怪事情的模块。至于包的例子,'collections'是Python 3中的一个包,'collections.abc'作为子模块。还有'multiprocessing'和其他一些。 – user2357112