通俗理解装饰器
解释:通过闭包来实现装饰器,函数作为外层函数的传入参数,然后在内层函数中运行、附加功能,随后把内层函数
作为结果返回。
1、python 装饰器是一种函数,一种返回值也是函数的函数
2、python装饰器可以在不改变函数的基础上,为该函数增加新功能
3、装饰器的作用就是增强函数功能,特点是简洁
4、装饰器最大的优势是用于解决重复性的操作,其主要使用的场景有如下几个:
计算函数运行时间
给函数打日志
类型检查
装饰器的简单使用
运行时间统计:
# 直接编译:
from time import time, sleep
def fun_one():
start = time()
sleep(1)
end = time()
cost_time = end - start
print("func one run time {}".format(cost_time))
def fun_two():
start = time()
sleep(1)
end = time()
cost_time = end - start
print("func two run time {}".format(cost_time))
def fun_three():
start = time()
sleep(1)
end = time()
cost_time = end - start
print("func three run time {}".format(cost_time))
# 装饰器编译
def run_time(func):
def wrapper():
start = time()
func() # 函数在这里运行
end = time()
cost_time = end - start
print("func three run time {}".format(cost_time))
return wrapper
@run_time
def fun_one():
sleep(1)
@run_time
def fun_two():
sleep(1)
@run_time
def fun_three():
sleep(1)
注:通过编写一个统计时间的装饰器run_time,函数的作为装饰器的参数,然后返回一个统计时间的
函数wrapper,这就是装饰器的写法,用专业属于来说这叫闭包(函数重要概念),简单来说就是函数
内嵌套函数。然后再每个函数上面加上@run_time来调用这个装饰器对不同的函数进行统计时间。
带参数的装饰器
def logger(msg=None):
def run_time(func):
def wrapper(*args, **kwargs):
start = time()
func() # 函数在这里运行
end = time()
cost_time = end - start
print("[{}] func three run time {}".format(msg, cost_time))
return wrapper
return run_time
@logger(msg="One")
def fun_one():
sleep(1)
@logger(msg="Two")
def fun_two():
sleep(1)
@logger(msg="Three")
def fun_three():
sleep(1)
fun_one()
fun_two()
fun_three()
类装饰器
dclass logging(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print "[DEBUG]: enter function {func}()".format(
func=self.func.__name__)
return self.func(*args, **kwargs)
@logging
def say(something):
print "say {}!".format(something)
保留元信息的装饰器
函数携带的一些基本信息,例如函数名、函数文档等,我们可以通过func.__name__获取函数名、
可以通过func.__doc__获取函数的文档信息,用户也可以通过注解等方式为函数添加元信息。
from time import time
def run_time(func):
def wrapper(*args, **kwargs):
start = time()
func() # 函数在这里运行
end = time()
cost_time = end - start
print("func three run time {}".format(cost_time))
return wrapper
@run_time
def fun_one():
'''
func one doc.
'''
sleep(1)
fun_one()
print(fun_one.__name__)
print(fun_one.__doc__)
# 输出
# wrapper
# None
######################################################
# 使用Python自带模块functools中的wraps来保留函数的元信息
from time import time
from functools import wraps
def run_time(func):
@wraps(func) # <- 这里加 wraps(func) 即可
def wrapper(*args, **kwargs):
start = time()
func() # 函数在这里运行
end = time()
cost_time = end - start
print("func three run time {}".format(cost_time))
return wrapper
@run_time
def fun_one():
'''
func one doc.
'''
sleep(1)
fun_one()
print(fun_one.__name__)
print(fun_one.__doc__)
# 输出
# fun_one
# func one doc.
内置装饰器
@staticmathod:静态方法
@classmethod:类方法
@property:私有方法
语法糖
python内置的 @ 语法就是为了简化装饰器的使用。