Python中神奇的装饰器

0.引入

python函数装饰器目的在于不改变原有函数的源代码情况下,给函数增加新的功能。而这正符合工程开发中的封闭开放原则,可以更好地服务于面向对象的开发。

整个设计过程可以理解为把原有函数放到新的函数当中,作为一部分功能的实现,进而实现了对于原有功能的扩充。

在下文中,笔者将分别就不同的函数情况对装饰器的设计展开讨论。

1.原函数没有需要输入的参数

def decorate(fn):
    def inner():
        print("你好!")
        fn()
    return inner
    

@decorate
def Test():
    print("hello!")


if __name__ == "__main__" :
    Test()

注意在写装饰器函数时,内层函数写完后需要在装饰器函数中返回内层函数。

2.原函数中有需要传入的参数

def decorate(fn):
    def inner(a,b):
        print("你好!")
        fn(a,b)
    return inner
    

@decorate
def Sum(a,b):
    print(a+b)


if __name__ == "__main__" :
    Sum(1,1)

注意:需要在inner和fn后面加上和原函数一样的参数。

3.原函数中有返回值

def decorate(fn):
    def inner(a,b):
        print("你好!")
        return fn(a,b)
    return inner
    

@decorate
def Sum(a,b):
    return a+b
    


if __name__ == "__main__" :
    print(Sum(2,1))

注意:需要在fn()前加上return,让inner函数有返回值

4.装饰器函数引入新的参数

def outter(flag):
    def decorate(fn):
        def inner(a,b): 
            print("你好!")
            print(flag)
            return fn(a,b)
       
        return inner
    return decorate
    
    


@outter(1)
def Sum(a,b):
    return a+b
    


if __name__ == "__main__" :
    print(Sum(2,1))

注意:这种情况相对上述比较复杂,需要在外层加上一层新的函数outter,用来传递新的参数。

(1)需要return decorate

(2)需要把@decorate 改成 @outter(外部函数的名字)

5.用于计时的装饰器的例子

import time

def decorate(fn):
    def inner():
        a=time.time()
        fn()
        b=time.time()
        return b-a
    return inner


@decorate
def arr():
    li=[]
    for i in range(1000):
        li.append(i)


if __name__ =="__main__":
    print(arr())

除了用装饰器计时,把算法封装在函数内,检验算法的时间复杂度,还可以用另一种方法。

import timeit
def arr():
    li=[]
    for i in range(1000):
        li.append(i)
timeit.timeit("arr()",globals=globals(),number=1000)     #number表示计算1000次取平均值

总的来说,装饰器常常具有通用性,函数经过装饰后,调用原函数,相当于调用inner函数,也可以根据此更好地设计装饰器结构。

对于多装饰器,离函数越近的先装饰,可以理解为经过内层装饰器装饰装饰后原函数变为inner1函数,inner1函数作为新的fn被外层装饰器装饰,形成新的函数inner2,相当于最后调用原函数就在调用inner2函数。

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值