python之装饰器

在python中,装饰器的作用就是在不改变函数本身的前提下,可以对函数增加装饰,先举个例子

def outer(func):     #装饰函数
    def inner():
        print("before")
        func()
        print("after")
    return inner

def f1():   #被装饰的函数
    print("fffff")
f1 = outer(f1)
f1()

 

执行过程:

 

发现outer函数,不执行内部结构,扔内存

发现f1函数,不执行内部结构,扔内存

执行outer函数 参数是 f1函数名 

进入outer函数,发现inner函数,不执行内部结构,扔内存

 执行return 返回inner函数的函数名

从outer函数出来,将 inner函数名 赋给 f1, 此时 f1 已被覆盖成为 inner函数的别名,

执行 f1(),这里实际上就是执行inner函数

进入inner函数内部,输出before

调用func()   func参数是传递进来的f1函数名,所以实际上调用的是 f1()  原函数      

进入f1函数体,输出fffff

退出f1()函数,继续执行输出  after

结束

 

从这个例子可以看出,在没有改变f1函数的内部结构的同时,  在我们调用f1时使它还能输出before   after

 相当于装饰了f1函数            

 

而我们上述代码可以改写为

def outer(func):
    def inner():
        print("before")
        func()
        print("after")
    return inner

@outer
def f1():
    print("fffff")
f1()

等效于第一个代码

@outer 完成了 

f1 = outer(f1)

 便于书写          实际中都是     @+装饰函数  (不是被装饰函数) 放在被装饰函数的上一行

我们执行f1函数, 就是执行装饰函数里的 inner函数

 

补充

 

1.这里有人可能就有疑问,这么麻烦,我直接写到f1函数中不就行了

  这里的解释是 开发封闭原则    

   简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:

  • 封闭:已实现的功能代码块
  • 开放:对扩展开发                      

举个简单的例子

假设很多业务处理都需要调用一个特定的方法,当某一个业务需要修改功能时,而又必须修改其调用的特定方法内部,如果直接修改该方法,这个业务是解决问题了,但这样就会造成其他业务产生问题。

 

2.  函数如果没有返回值,默认返回None

    上述代码 在装饰器函数outer中 如果return inner()

    会执行inner() 然后inner函数没有返回值 返回None 

    return None

    所以这里不能加()  仅仅是函数名的赋值  

 

 执行func()时  执行这里f1()是原f1()    因为将f1传递给形参之后,func已经指向了f1函数的内存地址,f1函数名才被改变的 然后调用的func()

返回去再看一遍就明白了~

 

 

第二弹~

def outer(func):
    def inner():
        print("before")
        i = func()
        print("after")
        return i
    return inner

@outer
def f1():
    print("fffff")
    return "OK"
f1()i = func()
        print("after")
        return i
    return inner

@outer
def f1():
    print("fffff")
    return "OK"
f1()

和第二份源码不同的是,这个被装饰函数有返回值,我们装饰器的目的是在不改变函数本身的前提下,可以对函数进行装饰

而我们的被装饰函数返回 ok   所以我们要变成加粗的样子

当然我们不能写成

 def inner():
        print("before")
        return func()
        print("after")
    return innerreturn func()
        print("after")
    return inner

print("after")就不会被执行了

 

 

        

 

  

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值