关于python的装饰器使用(单层,双层嵌套)

本文详细探讨了Python装饰器的使用,包括简易装饰器和双层装饰器的运行顺序。通过实例分析,揭示了装饰器在外层方法未调用时依然执行的特点,以及装饰器嵌套时函数调用的层次关系。强调了装饰器中返回值的重要性,以及装饰器在外层执行的特性。
摘要由CSDN通过智能技术生成

写作思路

本文主要讲述装饰器的使用以及装饰器整个运行流程的顺序!!!
1、简易装饰器及运行顺序的分析
2、双层装饰器及运行顺序的分析
3、总结

1、简易装饰器

①被包裹函数内的执行顺序

# -*- coding: utf-8 -*-
from functools import wraps


def MyDecorator(func):
    def wrapper(arg1, arg2, arg3):
        print("run in decorator before func", arg1, arg2, arg3)
        func(arg1, arg2, arg3)
        print("run in decorator after func", arg1, arg2, arg3)

    return wrapper

@MyDecorator
def test(a, b, c):
    print("run in function", a, b, c)


if __name__ == '__main__':
    test(10, 20, 30)

运行结果如下
在这里插入图片描述
基于上述结果,我们不难看出,被装饰函数的运行其实就是装饰器内func的运行位置,基于上述思想,我们还可以把 func 放在装饰器内的任意位置,比如下面这样

②被包裹函数的外层上方

def MyDecorator(func):
    func(100, 200, 300)

    def wrapper(arg1, arg2, arg3):
        print("run in decorator before func", arg1, arg2, arg3)
        func(arg1, arg2, arg3)
        print("run in decorator after func", arg1, arg2, arg3)

    return wrapper

运行结果:
在这里插入图片描述
或者这样
③被包裹函数的外层下方

def MyDecorator(func):

    def wrapper(arg1, arg2, arg3):
        print("run in decorator before func", arg1, arg2, arg3)
        func(arg1, arg2, arg3)
        print("run in decorator after func", arg1, arg2, arg3)
    func(100, 200, 300)

    return wrapper

运行结果:
在这里插入图片描述
哈哈哈哈 看到没有 上面的运行结果是一样的!!千万别掉坑里去,因为wrapper是返回的函数,因此他要在返回之后才会被调用!所以外层的函数一定是会先执行的!!!

2、双层装饰器

①装饰器外层如果有方法时的深层分析

# -*- coding: utf-8 -*-
from functools import wraps


def DoubleDecorator(flagStr, name=None, message=None):
    print("1111111", flagStr, name, message)

    def decorate(func):
        print("2222222", flagStr, name, message)

        @wraps(func)
        def wrapper(arg1, arg2):
            print("3333333", flagStr, name, message)
            res = func(arg1, arg2)
            print("4444444", flagStr, name, message)
            return res

        return wrapper
    print("5555555", flagStr, name, message)
    return decorate


@DoubleDecorator("True", "addFunction", "run by add")
def add(x, y):
    print("run in add function", x, y)
    return x + y


if __name__ == '__main__':
    # print("run in main thread ", add(1, 2))
	pass

注意看哇,此时我们是没有调用被装饰的函数 add的!!
但是运行结果如下:

在这里插入图片描述
先别急着做分析,我们再回过头来看看上一个例子,此时我们做同样的处理

# -*- coding: utf-8 -*-
from functools import wraps


def MyDecorator(func):
    def wrapper(arg1, arg2, arg3):
        print("run in decorator before func", arg1, arg2, arg3)
        func(arg1, arg2, arg3)
        print("run in decorator after func", arg1, arg2, arg3)
    func(100, 200, 300)

    return wrapper

@MyDecorator
def test(a, b, c):
    print("run in function", a, b, c)


if __name__ == '__main__':
    # test(10, 20, 30)
    pass

运行结果如下:
在这里插入图片描述
只要我们使用了装饰器,那么不管这个函数是否被调用,装饰器外层的方法都会运行的!并且装饰了几个函数就会运行几次!!!

②双层装饰器的运行顺序

if __name__ == '__main__':
    print("run in main thread ", add(1, 2))

运行结果如下:
在这里插入图片描述
分析可知:包裹在越内层的函数,被调用的时机就越晚,就和我们最上面简易的装饰器是一样的!
PS.记得在最内层要把res返回,不然在main运行的输出会打印出None哦!

3、总结

1、被装饰的函数无论是否调用,装饰器外层的方法都会被运行
2、装饰器的越外层的函数会越早被运行(其实就是很正常的事,但是脑子一热就忘记了)
3、对于有返回值的被装饰函数,记得要在内层把值返回,不然被装饰函数的工作就白做啦!(当然你要是只想在装饰器内得到被装饰函数的返回值我也没意见)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值