Python importlib講解
Python標准庫中提供了importlib模塊,目的是提供import語句(還有import())的底層實現,另外,importlib讓程序員可以在導入過程中創建自己的對象。之前的imp模塊在Python3.4中被importlib取代了。
importlib模塊非常復雜,下面只講解其中的一部分內容。
—————————————————————————————————————————————————————————————————————————
動態導入
importlib支持通過字符串動態導入模塊,如:
imoprt importlib #導入foo.py模塊 foo = importlib.import_module('foo') foo.main()
模塊導入檢查
導入模塊當模塊不存在時會拋出ImportError異常,如果我們想在導入模塊之前檢查該模塊是否可以被導入,可以使用importlib模塊進行檢查,如下:
import importlib.util def check_module(module_name): """檢查模塊時候能被導入而不用實際的導入模塊""" module_spec = importlib.util.find_spec(module_name) if module_spec is None: print('Module: {} not found'.format(module_name)) return None else: print('Module: {} can be imported!'.format(module_name)) return module_spec def import_module_from_spec(module_spec): """通過傳入模塊的spec返回新的被導入的模塊對象""" module = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module) return module if __name__ == '__main__': module_spec = check_module('fake_module') module_spec = check_module('collections') if module_spec: module = import_module_from_spec(module_spec) print(dir(module))
從源文件中導入
importlib.util工具還有一個功能,可以在僅僅知道模塊名字和路徑的情況下通過該工具導入,如下:
import importlib.util def import_source(module_name): module_file_path = module_name.__file__ module_name = module_name.__name__ module_spec = importlib.util.spec_from_file_location(module_name, module_file_path) module = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module) print(dir(module)) msg = 'The {module_name} module has the following methods: {methods}' print(msg.format(module_name=module_name, methods=dir(module))) if __name__ == '__main__': import os import_source(os)
import_from_github_com
有一個優雅的模塊import_from_github_com可以從github中尋找並加載模塊,該模塊使用了PEP 302中提供的import hook來實現功能。該模塊並沒有使用importlib模塊,而是使用pip安裝模塊,如果pip沒有安裝則使用Python的import()函數實際導入新的安裝模塊。