Python之简单使用inspect.signature(fn).parameters判断函数参数和默认值
参考官方文档: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