基础理解
- 装饰器本质是函数,用来装饰其他函数。也就是为其他函数添加附加功能
- 有自己特定的原则
(1)不能修改被装饰函数的源代码
(2)不能修改被装饰函数的调用方式
3.实现装饰器 ( 高阶函数 + 嵌套函数 =》装饰器 )
(1)函数即变量
(2)高阶函数
a,把一个函数名当做实参传给另一个函数(不修改被装饰函数源代码的情况下,为函数增加功能)
b,返回值包含函数名(不修改函数的调用方式)
eg:
def hi():
print("in the hi ")
def test1(func):
print(func)
func()
test1(hi)
运行结果:
<function hi at 0x00000180FCFFD620>
in the hi
将hi()函数当做一个参数hi传给test1()函数,test1()在运行到func()时,hi替换func,变成了hi(),跳转到hi()函数下运行内部代码,最后返回test1(hi)结果,通过debug可以清楚看到函数执行的先后顺序
(3)嵌套函数
闭包
在函数中又定义了函数,且内部函数引用了外部函数中的变量,就称为闭包
eg:
其实装饰器就是一个闭包,python装饰是拓展原来函数功能的一种函数,其特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
import time
def timmer(func):
def warpper(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs)
stop_time = time.time()
print(f"func的运行时间是{stop_time-start_time}")
return warpper
@timmer # 相当于 test1 = timmer(test1) test1()作为一个参数test1传入timmer(func)函数,执行timmer(test1)
def test1():
time.sleep(3)
print("in test 1")
test1()
运行结果
in test 1
func的运行时间是3.0075812339782715
Process finished with exit code 0
实例2
import time
def timmer(func):
def deco(*args, **kwargs): #代表可以传入任意参数,用于被装饰函数可能带有参数传入,即使不传入参数,加上这两个也不影响
start_time = time.time()
func(*args, **kwargs)
end_time = time.time()
print(f"运行时间是: {end_time - start_time}")
return deco
@timmer # 相当于test1传入timmer(func),执行timmer(test1)
def test1():
time.sleep(3)
print("in test1")
@timmer # 相当于test2传入timmer(func),执行timmer(test2)
def test2():
time.sleep(2)
print("in test 2")
test1()
test2()
运行结果
in test1
运行时间是: 3.000143051147461
in test 2
运行时间是: 2.000452995300293