python 装饰器
Posted 七月流火
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 装饰器相关的知识,希望对你有一定的参考价值。
装饰器的实质就是一个函数,可以对其他函数进行装饰,在不改变原函数代码的基础上增加新的功能,调用方式也不改变。
比如我们有两个函数sout1,sout2
import time
def sout1():
time.sleep(1)
print("this is sout1")
def sout2():
time.sleep(2)
print("this is sout2")
sout1()
sout2()
# 输出
# this is sout1
# this is sout2
现在我想让每个方法执行完时输出运行需要的时间
我们可以修改代码实现
import time
def sout1():
start = time.time()
time.sleep(1)
print("this is sout1")
end = time.time()
print("running time is",end-start)
def sout2():
start = time.time()
time.sleep(2)
print("this is sout2")
end = time.time()
print("running time is",end-start)
"""
输出
this is sout1
running time is 1.0009281635284424
this is sout2
running time is 2.0002005100250244
"""
一两个这样功能简单的还能改改,但要是许多函数,新增的功能复杂怎么办?
那我们最好使用装饰器来实现。
在使用装饰器前我们要先了解两个概念 高阶函数、嵌套函数
-
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
接受一个或多个函数作为输入
输出一个函数
我们已经定义了sout1这个函数
sout1() // 会调用函数 """ 输出 this is sout1 running time is 1.0009281635284424 """ print (sout) <function sout1 at 0x02CEB780>
因为万物皆对象嘛
所以函数也是对象
sout1存的是地址 是对象的引用
我们新增一个引用
hello = sout1 hello() """ 输出 this is sout1 running time is 1.0009281635284424 """
既然是对象 当然也能作为函数的参数和返回值
例:
def test(func): return func def sout(): print("hello world!") a = test(sout) a() """ 输出 hello world! """
嵌套函数
就是函数里面又定义一个函数
例:
def outer(): print("hello") def inner(): print("world!") inner() outer() """ 输出 hello world! """
开始实现
既然可以把函数当作参数传入,那..
我们不就可以把原有函数当作参数传进一个新的函数中,新增点功能在返回出来?
import time def sout1(): time.sleep(1) print("this is sout1") def decorate(func): start = time.time() func() end = time.time() print("running time is",end-start) decorate(sout1) """ 输出 this is sout1 running time is 1.0004260540008545 """
现在已经实现了不修改原有代码添加新功能了,但是调用方式和以前不一样了。
那怎么实现不修改原来的调用方式?还是sout1()进行调用?
我们已经知道函数也可以和变量一样,给它一个新的引用,进行调用
如:
x = 1
y = x
print(y)
"""
输出
1
"""
def sout1():
time.sleep(1)
print("this is sout1")
hello = sout1
hello()
"""
输出
this is sout1
"""
那我们想办法让进行装饰的函数 decorate() 也返回一个函数
然后 sout1 = decorate(sout1)
不就实现了sout1()
新增功能而不修改原代码,原调用方式?
所以我们可以把decorate()中的代码再封装一下
def sout1():
time.sleep(1)
print("this is sout1")
# 原decorate()
# def decorate(func):
# start = time.time()
# func()
# end = time.time()
# print("running time is",end-start)
#改为:
def decorate(func):
def inner():
start = time.time()
func()
end = time.time()
print("running time is",end-start)
return inner
sout1 = decorate(sout1)
sout1()
"""
输出
this is sout1
running time is 1.0003764629364014
"""
成功!
然而我们还是要在 原来的函数调用前
添加类似语句 sout1 = decorate(sout1)
这个事情python可以通过语法糖@来帮我们完成
def decorate(func):
def inner():
start = time.time()
func()
end = time.time()
print("running time is", end - start)
return inner
@decorate # 等同于 sout1 = decorate(sout1)
def sout1():
time.sleep(1)
print("this is sout1")
sout1()
?
以上是关于python 装饰器的主要内容,如果未能解决你的问题,请参考以下文章