第四篇
谈装饰器前,先了解一下函数的基础知识
## 定义加法函数
def add_a_b(a, b):
print(a+b)
## 将该加法函数赋给t,这样t也就是一个函数了,拥有加法功能
t = add_a_b
t(1,2)
"""
3
"""
# 在函数内部定义函数
def outer():
print("I'm in outer")
def inner():
print("I'm in inner of outer")
## 调用inner函数,且只能在ouer函数里面调用inner
inner()
outer()
"""
I'm in outer
I'm in inner of outer
"""
inner()
"""
NameError: name 'inner' is not defined
"""
# 函数中将另一个函数作为返回值返回
def outer():
print("I'm in outer")
def inner():
print("I'm in inner of outer")
## 调用inner函数,且只能在ouer函数里面调用inner
return inner
# 这里p相当于inner
p = outer()
p()
"""
I'm in outer
I'm in inner of outer
"""
import time
def runningtime(func):
def wrapper(*args, **kwargs):
## 添加计时功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("运行完{}花费了{}秒".format(func.__name__, interval))
return wrapper
def add_a_b(a, b):
print(a+b)
## equipped_func接收从runningtime返回的函数
equipped_func = runningtime(add_a_b)
equipped_func(1000,54489)
"""
55489
运行完add_a_b花费了0.0009965896606445312秒
"""
所谓装饰器是作用在函数身上的,主要是丰富函数的功能,并且非常方便。
假设我们写了10000个函数,我们想测试运行每个函数所需要的时间,那么可以用装饰器添加计算时间的功能:
import time
from functools import wraps
## 定义装饰器
def runningtime(func):
@wraps(func)
def wrapper(*args, **kwargs):
## 添加计时功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("运行完{}花费了{}秒".format(func.__name__, interval))
return wrapper
@runningtime
def add_a_b(a, b):
print(a+b)
add_a_b(1000,54489)
"""
55489
运行完add_a_b花费了0.00099945068359375秒
"""
与例子1.4对比不难发现在函数前面加上@runningtime
的作用就相当于function = runningtime(function)
。
from functools import wraps
import time
## 带参数的装饰器
def logging(logfile):
def runningtime(func):
@wraps(func)
def wrapper(*args, **kwargs):
## 添加计时功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("运行完{}花费了{}秒".format(func.__name__, interval))
## 将日志写入日志文件中
with open(logfile,'a') as f:
f.write(str(interval)+'\n')
return wrapper
return runningtime
@logging('test.txt')
def add_a_b(a, b):
print(a+b)
add_a_b(1000,54489)
"""
55489
运行完add_a_b花费了0.0030028820037841797秒
"""
在这里,带参数的装饰器起的作用相当于function = logging('test.txt')(function)
定义一个带参数的装饰器