真Python技巧實戰應用,函數參數自動收集并批量處理
前言
分享一個最近發現的實用小技巧。有時候我會封裝一下別人的庫中的某個功能函數,比如下面是一個第三方庫的函數:
函數的參數非常多。而我需要自定義一個與它參數一樣的函數,里面做一些小處理后,調用它的原函數:
- 為了讓函數有智能提示,這里不能使用 *args 與 **kws 收集參數
- 把傳入的字符串處理一下
這里的問題是,難道我一定要把參數逐一傳入原函數嗎?
- 上面的第29行代碼能不能簡化?
- 代碼 行 24-27 的處理能不能簡化?
我們首先要知道一點,函數的參數,其實與我們普通定義的變量沒有多大差別。區別只是函數參數只是從外部指定值。
既然函數的參數是普通的變量,那么很自然我們可以想到使用內置函數 locals 獲取本地變量字典:
- 行24:利用 locals 函數獲取所有參數的字典
- 行26:利用 ** 解包傳參調用
非常簡單地解決了問題。不過這里注意,最好在函數一開始的時候就做這個事情。這是因為如果在執行 locals 之前,你自己在函數中定義了變量,那么也會保存在 locals 里面。
- 行24:不能在調用 locals 之前定義變量
其實有了參數字典,批量處理字符串參數的問題就很容易解決。
雖然這里沒有什么問題,但是通常來說,我們不應該在遍歷時修改原字典。可以換成推導式或復制再修改
但是,現在我有好幾個這種間接調用的函數。難道每一個我都要像上面那樣寫一大串代碼嗎?
我一開始也想到,這不是很簡單事情嗎,把上面的代碼抽出來,到一個函數就可以:
需要時,調用即可:
真的可以嗎?
顯然不行。因為調用 locals 時,函數 strip_str_args 根本沒有任何參數!
辦法總比困難多,既然不能直接使用 locals ,那就讓外面傳進來吧:
調用的時候就需要使用 locals:
還能不能再簡化?每次都要傳入 locals ,不符合我的"懶人"風格。
以前我就有兩篇文章講解過調用棧。當 python 每次進入一個函數,都會啟用一個"幀棧",用于保存當前函數執行過程中的信息。這些信息當然包括了定義的變量。
其實 locals 函數就是從當前 "幀棧" 獲取的數據:
- 行16:導入 inspect 模塊
- 行20:獲取當前幀棧
- 行24: cur_frame.f_back 獲取上一層幀棧,就是調用這個函數的人的環境信息。 f_locals 相當于獲得了外部傳進來的 locals 字典
現在調用則很簡單了:
- 要確保在函數一開始調用
目前,還有一個限制,"確保在函數一開始調用" 。
這個限制能去掉嗎?