2017-05-24 103 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