国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中標準模塊importlib詳解

2019-11-25 16:14:49
字體:
來源:轉載
供稿:網友

1 模塊簡介

Python提供了importlib包作為標準庫的一部分。目的就是提供Python中import語句的實現(以及__import__函數)。另外,importlib允許程序員創建他們自定義的對象,可用于引入過程(也稱為importer)。

什么是imp?

另外有一個叫做imp的模塊,它提供給Python import語句機制的接口。這個模塊在Python 3.4中被否決,目的就是為了只使用importlib。

這個模塊有些復雜,因此我們在這篇博文中主要討論以下幾個主題:

•動態引入
•檢查模塊是否可以被引入
•引入源文件自身
•第三方模塊 import_from_github_com

2 模塊使用

2.1 動態引入

importlib模塊支持傳入字符串來引入一個模塊。我們創建兩個簡單的模塊來驗證這個功能。我們將會給予兩個模塊相同的接口,讓它們打印名字以便我們能夠區分它們。創建兩個模塊,分別為foo.py和bar.py,代碼如下所示,

def main(): print(__name__)

現在我們使用importlib來引入它們。讓我們看看這段代碼如何去做的。確保你已經把這段代碼放在與上面創建的兩個模塊相同的目錄下。

#importer.pyimport importlibdef dynamic_import(module): return importlib.import_module(module)if __name__ == "__main__": module = dynamic_import('foo') module.main() module_two = dynamic_import('bar') module_two()

在這段代碼中,我們手動引入importlib模塊,并創建一個簡單的函數dynamic_import。這個函數所做的就是調用importlib模塊中的import_module函數,入參就是我們傳入的字符串,然后返回調用結果。在代碼段的下面,我們調用每個模塊的main方法,將會打印出每個模塊的名稱。

在你的代碼中,你可能不會大量這樣做。當你只有一個字符串時,如果你想引入這個模塊,importlib就允許你可以這么做。

2.2 模塊引入檢查

Python有一個編碼規范就是EAPP:Easier to ask for forgiveness than permision。意思就是經常假設一些事情是存在的(例如,key在詞典中),如果出錯了,那么就捕獲異常。你可以看 Python標準模塊--import 文章中我們嘗試引入模塊,當它不存在時,我們就會捕獲到ImportError。如果我們想檢查并觀察一個模塊是否可以引入而不是僅僅是猜測,該如何去做?你可以使用importlib。代碼如下:

#coding:utf-8import importlib.utilimport importlibdef 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): module = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module) return moduleif __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。在check_module函數中,我們調用find_spec函數來檢查傳入的字符串作為模塊是否存在。首先,我們傳入一個假的名稱,然后我們傳入一個Python模塊的真實名稱。如果你運行這段代碼,你將會看到你傳入一個沒有安裝的模塊的名稱,find_spec函數將會返回None,我們的代碼將會打印出這個模塊沒有找到。如果找到了,我們就會返回模塊的說明。

我們可以獲取到模塊的說明,然后使用它來真正的引入模塊。或者你可以將字符串傳入到import_module函數中,正如我們在2.1節中所學習到的一樣。但是我們已經學習到如何使用模塊的說明。讓我們看一下上述代碼中的import_module_from_spec函數。它接受由check_module函數返回的模塊說明。我們將其傳入到module_from_spec函數,它將會返回引入的模塊。Python的官方文檔推薦,在引入模塊后執行它,所以我們下一步做的就是調用exec_module函數。最后我們返回這個模塊,并且運行Python的dir函數來確認這個我們就是我們所期望的。

2.3 從源文件中引入

在這一節中,我想說明importlib的子模塊util還有另外一個技巧。你可以使用util通過模塊名和文件路徑來引入一個模塊。示例如下所示,

#coding:utf-8import importlib.utildef 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 logging import_source(logging)

上述代碼中,我們實際引入了logging模塊,并將它傳入到import_source函數。在這個函數中,我們首先獲取到模塊的實際路徑和名稱。然后我們將這些信息傳入到util的spec_from_file_location函數中,這個將會返回模塊的說明。一旦我們獲取到模塊的說明,我們就可以使用與2.2節相同的importlib機制來實際引入模塊。

現在讓我們來看一個精巧的第三方庫,Python的__import__()函數直接引入github中的包。

2.4 import_from_github_com

這個精巧的包叫做import_from_github_com,它可以用于發現和下載github上的包。為了安裝他,你需要做的就是按照如下命令使用pip,

pip install import_from_github_com

這個包使用了PEP 302中新的引入鉤子,允許你可以從github上引入包。這個包實際做的就是安裝這個包并將它添加到本地。你需要Python 3.2或者更高的版本,git和pip才能使用這個包。

一旦這些已經安裝,你可以在Python shell中輸入如下命令,

>>> from github_com.zzzeek import sqlalchemyCollecting git+https://github.com/zzzeek/sqlalchemyCloning https://github.com/zzzeek/sqlalchemy to /tmp/pip-acfv7t06-buildInstalling collected packages: SQLAlchemyRunning setup.py install for SQLAlchemy ... doneSuccessfully installed SQLAlchemy-1.1.0b1.dev0>>> locals(){'__builtins__': <module 'builtins' (built-in)>, '__spec__': None,'__package__': None, '__doc__': None, '__name__': '__main__','sqlalchemy': <module 'sqlalchemy' from '/usr/local/lib/python3.5/site-packages//sqlalchemy/__init__.py'>,'__loader__': <class '_frozen_importlib.BuiltinImporter'>}

你如果看了import_from_github_com的源碼,你將會注意到它并沒有使用importlib。實際上,它使用了pip來安裝那些沒有安裝的包,然后使用Python的__import__()函數來引入新安裝的模塊。這段代碼非常值得學習。

2.5 總結

到這里,你已經了解到在你的代碼中如何使用importlib和引入鉤子。當然還有很多超出本文所覆蓋的知識,如果你需要寫一個自定義的引入器或者下載器,你需要花費很多時間來閱讀官方文檔和源碼。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 左云县| 九龙县| 明星| 德清县| 响水县| 高雄市| 阿瓦提县| 南丹县| 肇州县| 宝山区| 柳州市| 防城港市| 静宁县| 和静县| 通州区| 托里县| 上饶市| 民丰县| 庄浪县| 多伦县| 伊宁县| 伊春市| 睢宁县| 济宁市| 怀仁县| 原平市| 通江县| 繁昌县| 河北省| 吉木萨尔县| 鄂州市| 孟津县| 丰城市| 原阳县| 湖口县| 卓尼县| 博乐市| 高雄县| 安顺市| 清新县| 阳曲县|