Python之装饰器的实例

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
'''
 
 

本文为原创文章,转载请标明出处
原文地址:https://www.cnblogs.com/harden13/p/8891323.html