1.1装饰器的应用:参数类型检查
函数参数的检查,一定是在函数外 函数应该作为参数,传入到检查函数中 检查函数拿到函数传入的实际参数,与形参声明对比 __annotations__属性是一个字典,其中包括返回值类型的声明。假设要做位置参数的判断,无法和字典中的声明对应。使用inspect模块 inspect模块:提供获取对象信息的函数,可以检查函数和类、类型检查
from functools import wraps import inspect def check(fn): @wraps(fn) def _check(*args,**kwargs): sig = inspect.signature(fn) params = sig.parameters #传入的参数是有序的字典,标识的是函数的签名 keys = list(params.keys()) #把形参的参数从字典中提取出来,利用list函数迭代出来,在利用索引取值 values = list(params.values())#把形参的参数注解的类型拿到,用list函数迭代,在利用索引取值 for k,v in enumerate(args): #args实参迭代,k可以利用在索引取值上 print('k={},v={}'.format(k,v)) if isinstance(v,values[k].annotation): #拿到参数注解的类型 eg:int or str print("==") for key,val in kwargs.items(): if isinstance(val,params[key].annotation): print("==") result = fn(*args,**kwargs) return result return _check @check def add(x,y:str)->str: return x+y add(x='a',y='b') #print == 'ab'
def say_hi(func):
def wrapper(*args,**kwargs):
print('hi')
ret = func(*args,**kwargs)
print('bye')
return ret
return wrapper
def say_no(func):
def wrapper(*args,**kwargs):
print('yo')
return func(*args,**kwargs) #43
# print('rock & roll')
return wrapper
@say_hi # second 其次进行装饰 func = say_hi(func1) 最后执行func
@say_no # first 先进行装饰func func1 = say_no(func) say_no函数已经执行,但是return func #43这个位置没有被调用所以内层函数不执行
def func():
print('rock & roll')
func() # 相当于调用 @say_hi的内层嵌套函数
'''
def say_hi(func):
def wrapper(*args,**kwargs):
print('hi')
# ret = func(*args,**kwargs)
print('yo')
# return func(*args,**kwargs)
print('rock & roll')
print('bye')
return ret
return wrapper
def say_no(func):
def wrapper(*args,**kwargs):
print('yo')
# return func(*args,**kwargs)
print('rock & roll')
return wrapper
'''