两个装饰器的执行顺序

两个装饰器的执行顺序

如下,两个装饰器time_func 和auth_func分别实现了测试程序耗时和认证功能

import time
user_name = "zb"
user_pwd = "123"

def time_func(func1):
    print("time")
    def inner1():
        print("from inner1")
        start_time = time.time()
        func1()
        stop_time = time.time()
        print(stop_time-start_time)
    return inner1

def auth_func(func2):
    print("auth")
    def inner2():
        print("from inner2")
        name = input("input your name:").strip()
        pwd = input("input your password:").strip()
        if name == user_name and pwd == user_pwd:
            print("login successful")
            func2()
        else:
            print("name or password error")
    return inner2

@time_func
@auth_func
def test():
    print("from test")
test()

1.python解释器从上而下执行代码:导入时间模块,定义变量用户名和密码

2.遇到装饰器(闭包函数)time_func,申请了1片内存地址,函数名time_func指向了这片内存地址,程序继续向下执行(这里只是定义了函数,并不会执行,所以相当于1行代码)

3.遇到装饰器auth_func,这里同第2步,申请1片内存地址,函数名auth_func 指向这片内存地址,程序继续向下执行

4.解释器执行到装饰@time_func这里,此行代码下是一个装饰器@auth_func而不是一个函数,python解释器并不会执行装饰功能,程序继续向下执行

5.Python解释器执行到@auth_func,因为装饰的是一个函数test,定义test函数,申请一片内存地址,test指向它

6.装饰器@auth_func 就相当于test = auth_func(test)

①执行等号左边代码:test赋值给func2即func2指向了test的内存地址

②auth_func():执行函数auth_func,定义了函数inner2,申请1片内存地址,函数名inner2指向这片内存地址(此处并未调用函数,故看成1行代码),继续向下执行,返回inner2

③test接收返回值inner2即test指向了inner2的内存地址

7.装饰器@time_func执行,test = time_func(test),

①test赋值给func1即func1指向test的内存地址(此时test指向了inner2),故func1指向了inner2,

②定义了函数inner1,申请1片内存地址,函数名inner1指向这片内存地址(未调用函数,故看成1行代码),继续向下执行,返回inner1

③test接收返回值inner1,test指向了inner1的内存地址

8.调用函数test(),执行test指向的内存地址代码即inner1,inner1中的func1指向了inner2,inner2中的func2指向了test

inner1()

inner2()

test()

运行结果 inner1,inner2

实际运行结果如下,先装饰了auth_func,后装饰了time_func,先执行了计时功能,后执行了验证功能(此处特地延缓输入的时间,如果是先执行的验证功能,此处耗时应该很短)

倒个顺序装饰:耗时0.0s极快

总结:1.靠近函数的先装饰

? 2.先装饰的后执行

原文地址:https://www.cnblogs.com/robert-zhou/p/9985479.html

时间: 2024-08-28 17:02:31

两个装饰器的执行顺序的相关文章

python 中多个装饰器的执行顺序

python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inner1') ret = f1(*args,**kwargs) return ret return inner1 def wrapper2(f2): print('in wrapper2') def inner2(*args,**kwargs): print('in inner2') ret = f2

python3-多装饰器的执行顺序

[例]: def dec1(func): print("HHHA:0====>") def one(): print("HHHA:0.1====>") func() print("HHHA:0.2====>") return one def dec2(func): print("HHHB:0====>") def two(): print("HHHB:0.1====>") fu

TypeScript 装饰器的执行原理

装饰器本质上提供了对被装饰对象 Property? Descriptor 的操作,在运行时被调用. 因为对于同一对象来说,可同时运用多个装饰器,然后装饰器中又可对被装饰对象进行任意的修改甚至是替换掉实现,直观感觉会有一些主观认知上的错觉,需要通过代码来验证一下. 比如,假若每个装饰器都对被装饰对象的有替换,其结果会怎样? 多个装饰器的应用 通过编译运行以下示例代码并查看其结果可以得到一些直观感受: function f() { console.log("f(): evaluated")

关于多个装饰器装饰一个函数执行顺序的问题

我们通过两个实例来解开我们的疑惑: 实例一: def war1(func): def inner(*args, **kwargs): print("======war1 start=====") func(*args, **kwargs) print("======war1 end=====") return inner def war2(func): def inner(*args,**kwargs): print("======war2 start==

python 多个装饰器的调用顺序

python 多个装饰器的调用顺序 一般情况下,在函数中可以使用一个装饰器,但是有时也会有两个或两个以上的装饰器.多个装饰器装饰的顺序是从里到外(就近原则),而调用的顺序是从外到里(就远原则). 原代码 执行结果 装饰顺序 : 就近原则 被装饰的函数,组装装饰器时,是从下往上装饰 执行顺序 : 就远原则 装饰器调用时是从上往下调用 为了更好的理解,找到这段话: 被装饰的函数是一个妹子,装饰器是衣服."办事情"的时候得依次把外套.衬衣.内衣脱掉,事情办完了还要依次把内衣.衬衣.外套穿上.

装饰器,装饰器多参数的使用(*arg, **kwargs),装饰器的调用顺序

一.#1.执行outer函数,并且将其下面的函数名,当作参数 #2.将outer的返回值重新赋值给f1 = outer的返回值 #3.新f1 = inner #4.func = 原f1 1 #!/usr/bin/env python 2 def outer(func) : 3 def inner() : 4 print("hello") 5 print("hello") 6 print("hello") 7 r = func() 8 print(

装饰器(执行原函数前后可以有些操作)常用于设置访问权限

1. 需要先知道的知识点 # python是从上到下执行的 def f1(): print(123) def f2(): print(456) #这是执行f1() 输出456 # 函数整体是可以当做参数进行传递的 def f1(): print('123') def f2(xxx): xxx() f2(f1) # f1未加括号,相当于f1这个函数整体 解释器功能: 1. 自动执行@函数,并将其下面的函数名当作参数传递 2. 将@函数的返回值,重新赋值给下面的函数 在多层装饰器的情况下: 解释->

学习python的第十五天(函数的装饰器,两层装饰器和三层装饰器)

06.01自我总结 一.装饰器 1.函数装饰圈的定义 函数装饰器:一种装饰函数的函数 2.个人理解两层函数装饰器 两层函数装饰器个人觉得他其实就是把需要装饰的函数名丢入形参,然后用一个嵌套的函数对其头尾进行添加程序,但是不能减少他的程序内容,他的原来程序不变只能增不能减少,然后返回装饰好的子函数,再全局定义一个变量名与要装饰的函数名相同名字,并且将装饰后的函数调用赋予改变量. 1.简单的例子(无参函数) 如 #有个函数f1 def f1(): print('nick machachong') #

MyBatis拦截器的执行顺序引发的MyBatis源码分析

你猜一下哪个先执行?反正不要按常规来. 1 <plugins> 2 <plugin interceptor="com.Interceptor1"></plugin> 3 <plugin interceptor="com.Interceptor2"></plugin> 4 </plugins> 之前看有的博客分析源码,都没提到这一点.之前我只是用一下而已,这个顺序测试一下其实结论也很容易获得,但是