Python装饰器

python装饰器就是用来给原来的函数拓展功能的一种函数。
比如你有一段函数

import time
def demo():
    time.sleep(2)
	print('hello world')

假如你要给这段代码增加测试运行时间的功能,第一种方法,你可以这样写

import time
def demo():
	start = time.time()
    time.sleep(2)
	print('hello world')
	print(time.time() - start)

但是这样写需要对原函数进行改造,一般当函数比较多的时候需要一个一个重写,所以这种方法我们不提倡。这里还有第二种方法,

import time
def timer(func):
	start = time.time()
	func()
	print(time.time() - start)
	
def demo():
    time.sleep(2)
	print('hello world')

我们不改变原函数,而是另外定义一个测试函数时间的timer函数,我们在调用时可以这样写

timer(demo)

这时候将输出

hello world
2.0021307468414307

这里demo相当于一个变量,里面存放的是函数的地址,只有加上()才表示函数的调用,我们将demo的函数地址传入timer函数,用变量func接收,则变量func和变量demo的内容相同,都是函数的地址,这时候我们将func加()可以调用demo()函数,这样就可以完成测试函数时间的功能,但是这种方法改变了函数的调用方式,之前调用函数使用demo()变成了现在的timer(demo),在公司中不利于多人维护,所以我们也不推荐这样的方法。
----------------------------------------------------------------分割线----------------------------------------------------------------------
上面两种方法,在给函数添加新功能的时候,一个修改了函数的内容一个改变了函数的调用方式,都不是最理想的方法,有没有一种方法不会改变函数内容并且不会改变函数调用方式呢?那么就是我们python装饰器发挥作用的时候了。
首先装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数,关于闭包,有一个简单的解释:传送门。我们可以将上述代码改写为

import time
def timer(func):   装饰函数
	def inner():
		start = time.time()
		func()
		print(time.time() - start)
	return inner
@timer             语法糖
def demo():        被装饰函数
    time.sleep(2)
	print('hello world')

在这里,我们将timer写成一个闭包函数,内层函数为inner(),外层函数返回内层函数的地址,注意:函数只有加()的时候才表示调用,不加()就是保存地址的变量,这就是闭包。我们定义timer()是装饰器函数,demo()是被装饰函数,在被装饰函数demo的上方添加@timer就是装饰器的格式,其中(@装饰器函数)叫做语法糖。@timer表示执行timer函数,并将@timer下方的函数名作为参数赋值给timer函数,也就是将下放函数的地址作为参数传递到timer函数中,最后将timer函数的返回值也就是内部函数的地址重新赋值给下方函数。所以装饰器可以和下面的代码等价,只是换了一种写法,如果感觉看的不是很懂建议先搞懂函数闭包。

import time
def timer(func):   装饰函数
	def inner():
		start = time.time()
		func()
		print(time.time() - start)
	return inner

def demo():        被装饰函数
    time.sleep(2)
	print('hello world')
	
demo = timer(demo)   这里demo只是一个变量,里面可以保存任何函数的地址
demo()               通过地址调用函数

当使用了装饰器之后,这时候再调用程序

demo()

程序将会输出

hello world
2.0021307468414307

可以看到,我们一没有改变函数的内容,二没有改变函数的调用方式,就将一个新的功能赋予了函数demo,这就是python装饰器的作用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值