iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 26
0
Data Technology

30天python雜談系列 第 26

import雜談之五———淺談import_hook(真的很淺)

python import雜談之五

囉唆一下:寫完第30天的文章後才回來繼續補,所以這才是真正的最後一天文章呵呵~

前天與昨天介紹了sys.path初始化的機制以及pth是如何把路徑加進sys.path的,這可能讓許多人產生一種錯覺,好像import一個模組就只是把sys.path裏面的所有路徑都搜尋一遍,然後把符合模組名的py檔load進來而已。

這你就錯了!python的import機制可以藉著客製化而變的更有彈性,符合更多的需求,甚至你在import的過程中亂來都行XD,而所謂更多的需求可能像是你可以import遠端的模組、引入一個非py檔的文件或是對於對於被引入的模組做一些額外的檢查,我們就先從import指令運行的流程來做切入吧。

我試著比對一下(其實比對非常久)https://github.com/Liuchang0812/slides/tree/master/pycon2015cn以及官方文檔https://docs.python.org/3/reference/import.html的內容,我覺得當python在import一個模組時,他會先:

  1. 尋找sys.module看看是否這個模組已經有緩存了。
  2. 如果沒有,那他會先尋找sys.meta_path裏面的finder或importer對象,這些對象裏面定義了如何去尋找一個模組。
In python3 shell:
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib.PathFinder'>]
>>> 
  1. 從上面可知一開始python3預設有3種importer或finder,前面兩個我不是很懂,但當前面兩個importer都找不到時,第3個PathFinder就是規定了如何在sys.path中尋找需要的模組。
  2. 那這個PathFinder是如何去尋找模組呢?首先他使用了sys.path以及sys.path_hooks兩個對象,sys.path大家都知道了,而sys.path_hooks是一個由函式組成的list,對於每一項sys.path的路徑,其會被當作參數照順序傳入sys.path_hooks的每一個函式,若函式無法處理此路徑,就會引發ImportError,反之會傳回一個importer對象,而這個對象會幫我們把想要的模組load進來。

若我們想要做一個客製化的import機制,就必須自己建構一個import hook,主要有兩個方法,第一個是做一個Finder插入到sys.meta_path,這通常被稱做meta hook,另外一個就是去依靠PathFinder,做一個函式插入到sys.path_hooks裏面,但這個方法要確保你想要處理的路徑有在sys.path裏面,而這通常被稱做path hook。

如果明天還有時間的話我就補補看阿,但是真的好難阿嗚嗚...還是就這樣好了XD,這真得太難了我果然還是hold不來,ya現在放棄我就完賽了~。

如果還有人還想繼續深究的話可以參考以下網址:
http://python3-cookbook.readthedocs.io/zh_CN/latest/c10/p11_load_modules_from_remote_machine_by_hooks.html


上一篇
import雜談之四———來trace一下site模組
下一篇
decorator與closure雜談之一———初探decorator與函數對象
系列文
30天python雜談30

尚未有邦友留言

立即登入留言