Python装饰器的使用

本文介绍的是Python装饰器的使用,分三部分记录装饰器,旨在为之后复习保留学习笔记。python装饰器在没有改变原始函数调用方式的同时,在原始函数的前后增加功能,满足开放封闭原则。

1.

目录

1.装饰器的固定模板

2.带参数的装饰器模板

3.多个装饰器函数装饰一个函数

4.使用装饰器修饰类


1.装饰器的固定模板

# 装饰器的固定模板
def wrapper(f):
    def inner(*args, **kwargs):
        ret = f(*args, **kwargs)
        return ret
    return inner


@wrapper
def f():
    pass

f()

在装饰器wrapper函数定义时设置了一个参数f,此参数是用来接受被装饰函数的函数名。内部的inner函数接受动态参数用于传递给f函数,并用ret接受f调用后的返回值。以timer实例说明:

import time
def timer(f):
    def inner(*args, **kwargs):
        start = time.time()
        ret = f(*args, **kwargs)
        end = time.time()
        print(end - start)
        return ret
    return inner


@timer
def func(a):
    time.sleep(0.01)
    print("大家好", a)
    return '新年好'


# func = timer(func)
ret = func(1)
print(ret)

func函数是一个有参数且有返回值的普适函数,timer是装饰器函数,在内部f函数调用前后增加时间记录功能,并打印运行时间。

注释部分:# func = timer(func)等同于@timer操作,timer(func)函数执行后返回inner函数地址,此时的func=inner,之后ret=func(1)等同于ret=inner(1)

2.带参数的装饰器模板

def wrapper_out(arguments):
    def wrapper(func):
        def inner(*args, **kwargs):
            ret = func(*args, **kwargs) 
            return ret
        return inner
    return wrapper

@wrapper_out(arguments)
def f():
    pass

f()

带参数的装饰器是在装饰器函数上再增加一个闭包函数,@wrapper_out(arguments)先执行函数,wrapper_out(arguments)返回wrapper函数地址,@wrapper_out(arguments)等同于@wrapper

3.多个装饰器函数装饰一个函数

def wrapper1(func):
    def inner1(*args, **kwargs):
        print("wrapper1 before func")
        ret = func(*args, **kwargs)
        print("wrapper1 before func")
        return ret
    return inner1


def wrapper2(func):
    def inner2(*args, **kwargs):
        print("wrapper2 before func")
        ret = func(*args, **kwargs)
        print("wrapper2 before func")
        return ret
    return inner2

@wrapper2  # f = wrapper(f) f==inner1 --> f = wrapper2(inner1) = inner2
@wrapper1  # f = wrapper1(f) --> inner1
def f():
    print("in f")

f() # inner2()

@wrapper1 wrapper装饰的是f,因此@wrapper1等同于 f = wrapper1(f) 此时f = inner1。Python程序是从上往下执行的,@wrapper2装饰的是包含@wrapper1在内的整个函数,而@wrapper1内部其实是在执行inner1,因此@wrapper2等同于f = wrapper2(inner1),此时f是inner2的函数地址,执行f()时,等同于执行inner2(),但是inner2函数中的func此时是inner1,然后跳转至inner1函数执行,最后执行到原始的f函数。执行结果如下:

wrapper2 before func
wrapper1 before func
in f
wrapper1 before func
wrapper2 before func

现象是:外层的装饰器先执行,然后内层的装饰器再执行,然后递归推出函数调用

4.使用装饰器修饰类

参考链接:装饰器、装饰器类与类装饰器(三) - 简书 (jianshu.com)

参考文献:可能是全网最好的Python全栈合集【12部分完全版】_哔哩哔哩_bilibili

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值