python装饰器

最近看了下老男孩的关于python 装饰器的讲解,这里记录下自己的理解要看原文的请戳这里
预备知识
首先看下面代码
def f1():
    print("123")
def f1():
    print("456")
f1
f1()
IDLE中打印结果如下:
>>> f1
<function f1 at 0x04DE3270>
>>> f1()
456
>>> 
从这里可以看到2点
  1. 函数名 代指函数内部的代码(我的理解是这样~)
  2. 函数名() 这样的形式python才会执行python代码
再看下面代码
def outer(func):  #1
    def inner():  
        print("before")
        ret = func()
        print("after")
        return ret  #4
    return inner   

@outer         #2   
def f1():      #2   
    print("f1")

f1()           #3    

@函数名 就表示这是一个装饰器,以上面为例子,他有如下2个功能

  1. 自动执行 outer函数,并将其下面的函数名f1作为参数传入@后面的函数即outer(f1)
  2. @ 后面函数outer(f1)的返回值重新赋值给下面的函数f1 —-即f1 = outer(f1)的返回值 就是这里的作用
#2处会调用outer(f1),而在outer里面又定义了一个inner函数,现在只是定义,并没有执行,所以紧接着会执行 return inner 把inner返回了,返回给了谁?看第2点,返回给了f1,则此时新f1=inner,来看下新f1的函数体代码是什么,就是outer里面定义的inner函数
        print("before")
        ret = func()
        print("after")
        return ret 

其实这里的func就是老f1函数体代码,即

print("f1")

注意这里只是定义了,并没有执行
当有人在外面调用了f1 即#3处,现在才执行了inner里面的代码,效果如下

before
f1
after
#4处是为了f1可能有返会值,这里不能影响被装饰函数的执行效果
如果被装饰函数有参数,个数还能确定怎么办呢?

可以用万能参数,通过outer传进去,如下:

def outer(func):
    def inner(*arg,**kwargs):
        print("before")
        ret = func(*arg,**kwargs)
        print("after")
        return ret
    return inner

@outer
def f1(*arg,**kwargs):
    print("f1")

f1()
还有,一个函数可以被多个装饰器装饰吗?
可以的,如下代码
def outer2(func):
    def inner(*arg,**kwargs):
        print("before2")
        ret = func(*arg,**kwargs)
        print("after2")
        return ret
    return inner

def outer1(func):
    def inner(*arg,**kwargs):
        print("before1")
        ret = func(*arg,**kwargs)
        print("after1")
        return ret
    return inner

@outer2                      
@outer1                
def f1(*arg,**kwargs): 
    print("f1")

f1()
执行效果如下:
before2
before1
f1
after1
after2
可以这样看,先是outer1来装饰f1得到新的f1,再由outer2来装饰这个新的f1得到新新f1,调用的时候是执行新新f1.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值