Python基础知识15(# # 装饰器)

# 装饰器

# 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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值