# 装饰器
# 1 问题引出
def add(x, y):
print(f'add function called. x={x}, y={y} ') #侵入式代码, 不太容易剥离
# 非业务代码,写在这里是不好的。
return x + y
# sum1 = add(5,6)
# 可以把记录的功能抽取,形成一个函数:
# def multi(x, y):
# return x * y
# def logger(fn):
# print("调用前的增强功能")
# print(f'{fn.__name__} function called. ')
# ret = fn(4,6)
# print("调用后的增强功能")
# return ret
# res = logger(add)
# print(res)
# res2 = logger(multi)
# print(res2)
# print(add.__name__)
#***********************************************
# 解决参数问题
# 1
# def logger(fn, x, y):
# print("调用前的增强功能")
# print(f'{fn.__name__} function called. x={x}, y={y} ')
# ret = fn(x,y)
# print("调用后的增强功能")
# return ret
# r = logger(add, 6, 11)
# print(r)
# 2 fn的参数无法确定
# def my_sum(x,y,z,t, **kwargs):
# print(kwargs)
# return x + y+ z + t
# def logger(fn, x, y):
# # print("调用前的增强功能")
# print(f'{fn.__name__} function called. x={x}, y={y} ')
# ret = fn(x,y)
# # print("调用后的增强功能")
# return ret
# r = logger(my_sum, 6, 11)
# print(r)
# 3 解决参数问题
# 实参传递, 无非2中, 关键字和位置传参
# def logger(fn, *arg, **kwargs):
# # print("调用前的增强功能")
# print(f'{fn.__name__} function called. arg={arg}, kwargs={kwargs} ')
# ret = fn(*arg,**kwargs) # 意思就是把参数 原封不动的传递给fn, 二传手
# # print("调用后的增强功能")
# return ret
# r = logger(my_sum, 6, 11,5,6, name="bob")
# print(r)
#4 柯里化
# def my_sum(x,y,z,t, **kwargs):
# print(kwargs)
# return x + y+ z + t
# def logger(fn):
# def wrapper(*arg, **kwargs):
# # print("调用前的增强功能")
# print(f'{fn.__name__} function called. arg={arg}, kwargs={kwargs} ')
# ret = fn(*arg,**kwargs) # 意思就是把参数 原封不动的传递给fn, 二传手
# # print("调用后的增强功能")
# return ret
# return wrapper #包裹
# # r = logger(my_sum, 6, 11,5,6, name="bob")
# new_func = logger(my_sum) # => wrapper func
# r = new_func(6, 11,5,6, name="bob")
# print(r)
# 5 装饰器的内部实现
# def my_sum(x,y,z,t, **kwargs):
# print(kwargs)
# return x + y+ z + t
# def logger(fn):
# def wrapper(*arg, **kwargs):
# # print("调用前的增强功能")
# print(f'{fn.__name__} function called. arg={arg}, kwargs={kwargs} ')
# ret = fn(*arg,**kwargs) # 意思就是把参数 原封不动的传递给fn, 二传手
# # print("调用后的增强功能")
# return ret
# return wrapper #包裹
# # r = logger(my_sum, 6, 11,5,6, name="bob")
# my_sum = logger(my_sum) # => wrapper func
# r = my_sum(6, 11,5,6, name="bob")
# print(r)
# 6 引出装饰器
# def logger(fn):
# def wrapper(*arg, **kwargs):
# # print("调用前的增强功能")
# print(f'{fn.__name__} function called. arg={arg}, kwargs={kwargs} ')
# ret = fn(*arg,**kwargs) # 意思就是把参数 原封不动的传递给fn, 二传手
# # print("调用后的增强功能")
# return ret
# return wrapper #包裹
# @logger #装饰器 my_sum = logger(my_sum) =》wrapper
# def my_sum(x,y,z,t, **kwargs):
# print(kwargs)
# return x + y+ z + t
# r = my_sum(6, 11,5,6, name="bob")
# print(r)
# 7总结 无参装饰器
# @标识符
# 标识符指向一个函数,用一个函数来装饰它下面的函数,logger函数称为装饰器函数,
# my_sum 称为被装饰或被包装函数
# #本质上来看, 无参装饰器logger 实际上等效为一个参数的函数
# 8 完善一下功能
import time
import datetime
def logger(fn):
def wrapper(*arg, **kwargs):
# print("调用前的增强功能")
start = datetime.datetime.now()
ret = fn(*arg,**kwargs) # 意思就是把参数 原封不动的传递给fn, 二传手
delta = (datetime.datetime.now() - start).total_seconds()
print(f"function {fn.__name__} took {delta:.2f} seconds")
# print("调用后的增强功能")
return ret
return wrapper #包裹
@logger #装饰器 my_sum = logger(my_sum) =》wrapper
def my_sum(x,y,z,t, **kwargs):
# print(kwargs)
time.sleep(3)
return x + y+ z + t
r = my_sum(6, 11,5,6, name="bob")
print(r)