參考官方文檔:https://docs.python.org/zh-cn/3.7/library/inspect.html
inspect
inspect 模塊提供了一些有用的函數幫助獲取對象的信息,例如模塊、類、方法、函數、回溯、幀對象以及代碼對象。例如它可以幫助你檢查類的內容,獲取某個方法的源代碼,取得並格式化某個函數的參數列表,或者獲取你需要顯示的回溯的詳細信息。
該模塊提供了4種主要的功能:類型檢查、獲取源代碼、檢查類與函數、檢查解釋器的調用堆棧。
本章簡單介紹inspect.signature(fn).parameters獲取函數參數的參數名,參數的屬性,參數的默認值
示例
D:\learn-python3\學習腳本\inspect檢查對象\use_inspect.py
# 導入模塊
import inspect
def foo(a,b=1,*c,d,**kw):
pass
# 獲取函數參數返回一個有序字典
parms = inspect.signature(foo).parameters
print(parms)
#
# 獲取參數名,參數屬性,參數默認值
for name,parm in parms.items():
print(name,parm.kind,parm.default)
關於函數的參數參考:https://www.cnblogs.com/minseo/p/14816422.html
以上例子,我們定義了一個測試函數,其中參數a,b是位置參數,b有默認值,c加了*號代表可變參數,d因為接在帶*號的參數c后,所以d為關鍵字參數,關鍵字參數需要使用參數名傳遞加等於的值傳遞值
遍歷郵箱字典,其中key即為參數名,parm為參數的屬性,使用kind輸出是什么參數,比如位置參數,可變參數,關鍵字參數,字典參數,defalu為默認值
輸出如下
a POSITIONAL_OR_KEYWORD <class 'inspect._empty'> b POSITIONAL_OR_KEYWORD 1 c VAR_POSITIONAL <class 'inspect._empty'> d KEYWORD_ONLY <class 'inspect._empty'> kw VAR_KEYWORD <class 'inspect._empty'>
很明顯a,b為位置參數,c為可變參數,d為關鍵字參數,kw為字典參數
官方的參數屬性列表為
| 名稱 |
含義 |
|---|---|
| POSITIONAL_ONLY |
Value must be supplied as a positional argument. Python has no explicit syntax for defining positional-only parameters, but many built-in and extension module functions (especially those that accept only one or two parameters) accept them. |
| POSITIONAL_OR_KEYWORD |
Value may be supplied as either a keyword or positional argument (this is the standard binding behaviour for functions implemented in Python.) |
| VAR_POSITIONAL |
A tuple of positional arguments that aren't bound to any other parameter. This corresponds to a |
| KEYWORD_ONLY |
Value must be supplied as a keyword argument. Keyword only parameters are those which appear after a |
| VAR_KEYWORD |
A dict of keyword arguments that aren't bound to any other parameter. This corresponds to a |
根據以上我們可以寫出以下幾個函數判斷函數的參數
# 定義函數傳遞參數為函數,然后取出參數進行判斷
# 如果函數參數包含關鍵字參數並且關鍵字參數值為空則返回關鍵字參數的元組
def get_required_kw_args(fn):
args = []
params = inspect.signature(fn).parameters
for name, param in params.items():
if param.kind == inspect.Parameter.KEYWORD_ONLY and param.default == inspect.Parameter.empty:
args.append(name)
return tuple(args)
# 如果有關鍵字參數則取出返回元組
def get_named_kw_args(fn):
args = []
params = inspect.signature(fn).parameters
for name, param in params.items():
if param.kind == inspect.Parameter.KEYWORD_ONLY:
args.append(name)
return tuple(args)
# 判斷函數是否有關鍵字參數,如果有則返回True
def has_named_kw_args(fn):
params = inspect.signature(fn).parameters
for name, param in params.items():
if param.kind == inspect.Parameter.KEYWORD_ONLY:
return True
# 判斷函數是否有字典參數,如果有則返回True
def has_var_kw_arg(fn):
params = inspect.signature(fn).parameters
for name, param in params.items():
if param.kind == inspect.Parameter.VAR_KEYWORD:
return True
# 判斷函數的參數有沒有request,如果有request參數則把found賦值為True並結束本次循環繼續判斷其他參數
# 如果其他參數不是可變參數,也不是關鍵字參數,也不是字典參數則拋出錯誤
# 例如響應函數index(request)只有一個參數request所以在執行第一個if以后就沒有參數循環了,退出整個循環返回found的值為True
def has_request_arg(fn):
sig = inspect.signature(fn)
params = sig.parameters
found = False
for name, param in params.items():
if name == 'request':
found = True
continue
if found and (param.kind != inspect.Parameter.VAR_POSITIONAL and param.kind != inspect.Parameter.KEYWORD_ONLY and param.kind != inspect.Parameter.VAR_KEYWORD):
raise ValueError('request parameter must be the last named parameter in function: %s%s' % (fn.__name__, str(sig)))
return found
print(get_required_kw_args(foo),get_named_kw_args(foo),has_named_kw_args(foo),has_var_kw_arg(foo),has_request_arg(foo))
# ('d',) ('d',) True True False
def index(request):
pass
print(has_request_arg(index))
# True
輸出如下
('d',) ('d',) True True False
True
解析
get_required_kw_args(foo) # 有關鍵字參數d,並且默認值為空輸出參數名組成的元組 get_named_kw_args(foo)# 有關鍵字參數d,輸出參數名組成的元素 has_named_kw_args(foo)# 判斷有沒有關鍵字參數,有d輸出為True has_var_kw_arg(foo) # 判斷有沒有字典參數,有kw輸出為True has_request_arg(foo)# 判斷參數有沒有名字為request的,沒有輸出False has_request_arg(index)# 函數index有名為default的參數,返回True
