(一)函数定义的弊端
def add(x, y):
return x + y
print(add(4, 5))
print(add('hello','word'))
print(add(4, 'word'))
难发现:由于不做任何类型检查,织到运行期间问题才显现出来,或者线上运行时才能暴漏出问题
难使用:函数的使用者看到函数的时候,并不知道你的函数的设计,并不知道应该传入什么类型的数据
如何解决这种动态语言定义的弊端
def add(x, y):
"""
:param x:
:param y:
:return:
"""
return x + y
print(help(add))
def add(x:int, y:int) -> int:
"""
:param x:
:param y:
:return:
"""
return x + y
print(help(add))
print(add(4, 5))
print(add('pyt','hon'))
print(add.__annotations__)
{'x': , 'y': , 'return': }
i:int = 3
import inspect
def add(x:int,y:int,*args,**kwargs) -> int:
print(*args,**kwargs)
return x + y
sig = inspect.signature(add)
print(sig,type(sig)) # 函数签名
print('parms:',sig.parameters) #OrderedDict
print('return:',sig.return_annotation)
print(sig.parameters['y'],type(sig.parameters['y']))
print(sig.parameters['x'].annotation)
print(sig.parameters['args'])
print(sig.parameters['args'].annotation)
print(sig.parameters['kwargs'])
print(sig.parameters['kwargs'].annotation)
(x:int, y:int, *args, **kwargs) -> int
parms: OrderedDict([('x', ), ('y', ), ('args', ), ('kwargs', )])
return:
y:int
*args
**kwargs
* inspect.isfunction(add) #是否是函数
* inspect.ismethod(add) #是否是类的方法
* inspect.isgenerator(add) #是否是生成器对象
* inspect.isgeneratorfunction(add) # 是否是生成器函数
* inspect.isclass(add) # 是否是类
* inspect.ismodule(inspect) # 是否是内建函数
* inspect.inbuiltin(print) # 是否是内建对象
还有很多is函数,需要的时候直接查阅inspect模块帮助
保存在元组中,是只读的
name,参数的名字
annotation,参数的注解,可能没有定义
default,参数的缺省值,可能没有定义
empty,特殊的类,用来标记default属性或者注释annotation属性的空值
kind,实参如何绑定到形参,就是形参的类型
POSITIONAL_ONLY # 值必须是位置参数提供
POSITIONAL_OR_KEYWORD # 值可以作为位置参数或者关键字参数提供
VAR_POSITIONAL # 可变位置参数 *args
KEYWORD_ONLY # keyword-only参数
VAR_KEYWORD # 可变关键字参数
import inspect
def add(x,y:int=7,*args,z,t=10,**kwargs) -> int:
return x + y
sig = inspect.signature(add)
print(sig)
print('params:',sig.parameters) #有序字典
print('return:',sig.return_annotation)
print('~~~~~~~~~~~~~~~~~~`')
for i,item in enumerate(sig.parameters.items()):
name,param = item
print(i + 1,name,param.annotation,param.kind,param.default)
print(param.default is param.empty,end = '\n\n')
1 x POSITIONAL_OR_KEYWORD
True
2 y POSITIONAL_OR_KEYWORD 7
False
3 args VAR_POSITIONAL
True
4 z KEYWORD_ONLY
True
5 t KEYWORD_ONLY 10
False
6 kwargs VAR_KEYWORD
True
有函数如下
def add(x,y:int=7) -> int:
return x + y
检查用户输入是否符合参数注解的要求
让用户感觉还是在调用add函数
对用户输入的数据和声明进行对比,如果不服可,提示用户
import inspect,functools
def check(fn):
@functools.wraps(fn)
def wrapper(*args,**kwargs):
sig = inspect.signature(fn)
params = sig.parameters
print(params)
values = list(params.values())
for i,p in enumerate(args):
param = values[i]
if params.annotation is not param.empty and not isinstance(p,param.annotation):
print(p,'!===',values[i].annotation)
for k,v in kwargs.items():
if params[k].annotation is not inspect._empty and not isinstance(v,params[k].annottation):
print(k,v,'!===',params[k].annottation)
return fn(*args,**kwargs)
return wrapper
@check
def add(x,y:int=7,*args,z,t=10,**kwargs) -> int:
return x + y