Python 装饰器

1.1 装饰器

1.装饰器是什么?

      装饰器简单来说就是在不改变代码的前提下,使代码拓展额外的功能。也就是修改其他代码功能的函数。(采用了闭包和把函数作为参数)

2.初始装饰器

1.将函数作为变量传递给另一个函数

      我们定义两个函数,funA() 和 funB(),将函数funB()作为参数传递给函数funA()

def funA(fun): #参数为函数的引用(函数的函数名就是函数的引用)
    print("start.....")
    fun() #添加一个小括号来调用一个函数
    print("end.....")

def funB():
    print("正在调用funB")

funA(funB) #将函数funB()作为参数传递给函数funA()

start.....
正在调用funB
end.....

      为了更加直观地看到调用过程,我们给函数运行加个延迟,这里使用time库里的sleep函数和time函数来进行。

import time  #引入time库

def funA(fun):
    print("start.....")
    start = time.time()
    fun()
    end = time.time()
    print("end.....")
    print("程序一共运行了{:.2f}秒".format(end - start))

def funB():
    time.sleep(3) #使运行延迟3秒
    print("正在调用funB")

funA(funB)

start.....
正在调用funB
end.....
程序一共运行了3.02秒      

2.语法糖

      如果每次想要实现不同效果,都要修改原有的代码的话,会使我们写起程序来很麻烦,这时候就轮到装饰器来发挥作用了。让我们在调用funB()的时候自觉调用funA()。

import time

def funA(fun):
    print("start.....")
    start = time.time()
    fun()
    end = time.time()
    print("end.....")
    print("程序一共运行了{:.2f}秒".format(end - start))
    
@funA  # funA(funB)
def funB():
    time.sleep(3)
    print("正在调用funB")

start.....
正在调用funB
end.....
程序一共运行了3.03秒

      这里的@funA 其实就是语法糖,它的实质写法是:funA(funB),我们将其赋值给一个变量进行输出会得到一样的结果。

import time

def funA(fun):
    print("start.....")
    start = time.time()
    fun()
    end = time.time()
    print("end.....")
    print("程序一共运行了{:.2f}秒".format(end - start))
    

def funB():
    time.sleep(3)
    print("正在调用funB")

a = funA(funB) # @funA

start.....
正在调用funB
end.....
程序一共运行了3.01秒

      使用装饰器不用去修改原来的代码,只需在函数上面加上一个@函数名即可,对于语法糖,他只是一种特殊的语法,可以使程序变得更加直观和简洁。  

3.多层装饰器

      Python支持多个装饰器作用在一个函数上,举个例子

def outsideA(fun):
    print("我是外部的A")
    def inner():
        x = fun()
        sum = x + 1
        print("我是内部的A,此时的结果为:",sum)
        return sum
    return inner

def outsideB(fun):
    print("我是外部的B")
    def inner():
        x = fun()
        sum = x * 5
        print("我是内部的B,此时的结果为:",sum)
        return sum
    return inner

def outsideC(fun):
    print("我是外部的C")
    def inner():
        x = fun()
        sum = x * x
        print("我是内部的C,此时的结果为:",sum)
        return sum
    return inner
# 相当于outsideA(outsideB(outsideC(test)))
@outsideA 
@outsideB
@outsideC
def test():
    print("我是test")
    return 2

print("结果为:",test())

程序的运行结果为: 

我是外部的C
我是外部的B
我是外部的A
我是test
我是内部的C,此时的结果为: 4
我是内部的B,此时的结果为: 20
我是内部的A,此时的结果为: 21
结果为: 21

      从得出的结果我们能看到,此时程序的执行顺序是先执行outsideC函数的外部代码,接着执行outsideB、outsideA函数的外部代码,然后分别执行outsideC、outsideB、outsideA的内部代码。

4.带参数的语法糖

        调用一个函数,相当于调用这个函数的引用

import time
#采用了闭包和把函数作为参数 就是装饰器
def logger(msg):
    def time_master(func):
        def call_func():
            start = time.time()
            func()
            stop = time.time()
            print(f"一共耗费了{(stop - start):.2f} 秒。")
        return call_func
    return time_master
    
@logger(msg="A") #这里是语法糖 具体写法是 funA = logger(msg="A")(funA) (传入两个参数,一个给logger() 一个给time_master())

def funA():
    time.sleep(2)
    print("正在调用funA...")
    
@logger(msg="B")#这里是语法糖 具体写法是 funB = logger(msg="B")(funB)
def funB():
    time.sleep(2)
    print("正在调用funB...")


funA()
funB()

正在调用funA...
一共耗费了2.02 秒。
正在调用funB...
一共耗费了2.02 秒。

这就是对于装饰器内容的介绍,欢迎补充!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学者山羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值