python import hook可以翻譯為python 探針。
它的實現原理涉及了以下幾個知識點:
1. python匯入協議
2. sys.meta_path
一,python匯入協議
python 中所有載入到記憶體的模組都放在 sys.modules。當import 乙個模 塊時首先會在這個列表中查詢是否已經載入了此模組,如果載入了則 只是將模 塊的名字加入到正在呼叫 import 的模組的 local 名字空間中。如果沒有載入則 從sys.path 目錄中按照模組名稱查詢模組檔案,模組檔案可以是 py、pyc、pyd,找到後將模組載入記憶體,並加入到 sys.modules 中,一般如果 指定模組沒在 sys.modules 中找到,將呼叫python 的匯入協議來查詢和載入 模組。
python 匯入協議機制是由查詢器finder和載入器loader構成。
查詢器finder的職責是找到指定的模組,然後提供乙個載入器來處理實際的匯入 行為。要註冊乙個查詢器只需要在 sys.path_hooks 列表中。查詢器不真正載入 模組。如果他們能夠找到指定的模組,他們返回乙個模組分支,即模組匯入相 關資訊的封裝,在載入模組時匯入機制運用的資訊。
查詢器物件finder需要實現如下find_module 方法:
finder.find_module(fullname, path=none)1
• 如果 finder 被裝入了 meta_path,這個方法會接受第二個引數,
• 如果 import 的是頂層模組:none,
• 如果 import 的是子模組或子包:path
• 如果找到模組需要返回乙個 loader 物件,沒找到需要返回 none
載入器loader需要實現如下load_module 方法
loader.load_module(fullname):
• 這個函式返回乙個被載入的模組或者丟擲異常
• 判斷傳入的 fullname 是不是已經在 sys.modules 中了,如果在的話loader 必須使用已經載入的模組,否則 reload 功能不能正常工作,如果fullname 不在 sys.modules 中,loader 必須新建乙個 module 並載入
• 在 loader 執行匯入的模組**之前,模組必須已經被匯入 sys.modules中,否則會引起無窮迭代
• 如果匯入失敗,loader 必須清除已經插入到 sys.modules 中的模組
通過自己實現這樣的包括查詢器和載入器鉤子程式能夠實現對 python 匯入行為的控制,擴充套件python載入模組的功能。
二。sys.meta_path
python 模組是通過import的方式引用的,當我們執行一行 from package import module as mymodule 命令時,python直譯器會查詢package這個包的module模組,並將該模組作為mymodule引入到當前的工作空間。import語句主要是做了二件事: 查詢相應的module 和載入module到local namespace 。
在import的第乙個階段,主要是完成了查詢要引入模組的功能,這個查詢的過程如下:
1. 檢查 sys.modules列表 (儲存了之前import的類庫的快取),如果module被找到,則⾛到第二步。
2. 檢查 sys.meta_path列表。meta_path 是乙個 list,⾥面儲存著一些 finder 物件,如果找到該module的話,就會返回乙個finder物件。
3. 檢查某些隱式的finder物件,不同的python實現有不同的隱式finder,但是都會有 sys.path_hooks, sys.path_importer_cache 以及sys.path。
4. 丟擲 importerror
從上面的過程中可以看出,當執行 import 相關的操作時,會觸發 sys.meta_path 列表中定義的finder物件。按照python匯入協議的規則,我們需要實現乙個import hook,只需要實現乙個finder物件和loader物件對應的find_module方法和load_module方法。要讓python直譯器import 模組的 時候觸發這個finder物件,只需要將這個物件的例項插入到sys.metapath列表中。
下面是乙個簡單的hellp world程式 我們通過import hook實現在載入模組時 列印查詢和載入的資訊:
print(http.version_info)load_module 方法返回乙個 module 物件,這個物件就是 import 的 module 物件了。 比如我上面那樣就把 http 替換為 sys 這個 module 了。
Python包 模組和包匯入詳解(import)
1.模組 module 1.1 模組定義 通常模組為乙個.py檔案,其他可作為module的檔案型別還有 pyo pyc pyd so dll module 可看作乙個工具類,可共用或者隱藏 細節,將相關 放置在乙個module以便讓 更好用 易懂,讓coder重點放在高層邏輯上。module能定義...
Python之import匯入機制
1.模組匯入時的搜尋路徑 當你匯入乙個模組,python 解析器對模組位置的搜尋順序是 1.當前目錄 2.如果不在當前目錄,python 則搜尋在 shell 變數 pythonpath 下的每個目錄 3.如果都找不到,python會察看預設路徑。linux下,預設路徑一般為 usr local l...
Python學習之路 模組詳解及import本質上
1.定義 模組 用來從邏輯上組織python 變數,函式,類,邏輯 實現乙個功能 本質就是.py結尾的python檔案。檔名 test.py,對應的模組名 test 包 用來從邏輯上組織模組的,本質是乙個資料夾或者目錄 必須帶乙個 init py檔案 2.匯入方法 import module nam...