為什麼需要檢查參數的型態?或者提取其詳細資訊?
讓我們先看下方Python Web框架,BoboGetting Started中的例子,說明這個機制被使用在哪裡:
這是一個bobo的官網的例子,我們將他改寫如下
import bobo
@bobo.query('/')
def hello(name):
return "Hello %s!" % name
然後我們將他Run起來:
bobo -f hello.py
仔細觀察以下兩個結果,第一個結果產生403,第二個結果成功"Hello max!",原因在於第二個方法多傳了"?name=max"給bobo,而第一個方法並未傳給bobo。
curl -i http://localhost:8080/
curl -i http://localhost:8080/?name=max
也就是說,bobo明確的知道,hello函數是需要一個name參數的,但是bobo是利用什麼方法知道的?
沒錯,就是利用__defaults__ +__code__或inspect!
下面是一個範例函數(此函數為取得指定長度的字串,並移除最後空格,不過實際做什麼不是此處重點。)
def clip(text, max_len=80):
"""Return text clipped at the last space before or after max_len
"""
end = None
if len(text) > max_len:
space_before = text.rfind(' ', 0, max_len)
if space_before >= 0:
end = space_before
else:
space_after = text.rfind(' ', max_len)
if space_after >= 0:
end = space_after
if end is None: # no spaces were found
end = len(text)
return text[:end].rstrip()
函數中有個 defaults 屬性,它是一個tuple,裡面保存著定位參數和關鍵字參數的默認值(僅限關鍵字參數的默認值在 kwdefaults 屬性中),而參數的名稱在 code 屬性中,它的值是一個 code 對象引用,自身也有很多屬性。
clip.__defaults__
clip.__code__
clip.__code__.co_varnames
依照以上的資訊,我們確實有一些方法可以推論出,參數是text/max_len,並且max_len的值預設為80,但顯得不那麼直覺,幸好,我們有inspect!
from inspect import signature
sig = signature(clip)
sig
str(sig)
for name, param in sig.parameters.items():
print(param.kind, ':', name, '=', param.default)
inspect._empty表示沒有預設值。
inspect.signature 函數返回一個 inspect.Signature Object,它有一個 parameters 屬性,這是一個有序映射,所以可以把參數名和 inspect.Parameter 一一對應起來,直覺許多了對吧~
那(bobo)框架又是怎麼實際的去判斷的呢?
inspect.Signature 中有個 bind 方法,它可以把任意個參數綁定到簽名中的形參上,實參到形參所用的匹配規則需要一模一樣。框架正式使用這個方法在真正調用函數前驗證參數。
my_para = {'text':'123456 8 1','max_len':80}
bound_args = sig.bind(**my_para) #傳入參數正確!
my_para = {'max_len':80}
bound_args = sig.bind(**my_para) #傳入參數錯誤!
其實這也與解釋器使用的機制相同,框架和 IDE 等工具可以使用這些信息驗證代碼!
以上就是本次內容,Python如何檢查函數的參數信息或獲取參數的信息,你學會了嗎?
Reference:
https://blog.louie.lu/2017/08/08/inspect-python-standard-library-11/
https://bobo.readthedocs.io/en/latest/
https://www.books.com.tw/products/0010706172
Share on Twitter Share on FacebookSQL Server Analytics Service 1
SEO(1) Github(2) Title Tag(2) ML(1) 李宏毅(1) SQL Server(18) Tempdb(1) SSMS(1) Windows(1) 自我成長(2) Excel(1) python Flask(1) python(5) Flask(2)
Max Chen (159)