python中,有一个高级功能是装饰器,毕业后转码面试大厂的时候,提问率超级高! 但是没太用过,后来接触到同事们的代码库,看到过,但是一直没深究,就在公共代码库ctrl+c/v与大佬们的代码保持格式一致......(菜的理不直气也壮).
如果小伙伴们有更多的业务经验与想法,欢迎交流!
今天就浅浅写点自己的理解:
一 装饰器的本质
装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能(:-)一个函数装饰下另外一个函数,发挥点小作用,美观代码,不想装饰了可以去掉),装饰器的返回值也是一个函数/类对象 .(我见过类的,后悔当时太忙没研究,休息时间只分配给了娱乐,我有罪)
二 长相
代码里出现 @ (英文名叫"语法糖" Syntactic Sugar)
三 业务场景
性能测试 打印日志(日志这东西有用啊,开发定位问题好帮手,在开发大佬们跟前观摩学习)
四 使用
python版本3.12
写着写着好像理解了(脑子里充满了知识的感jio)
先定义四个简简单单的函数,计算两数加/乘/除以/取余,然后一起调用
def func1(x, y=10):
print(x + y)
def func2(x, y=10):
print(x * y)
def func3(x, y=10):
print(x // y)
def func4(x, y=10):
print(x % y)
func1(10, 30)
func2(10, 30)
func3(20)
func4(10)
当你正在心里夸了自己800遍,我真聪明(玩一会交上去后)
主管意见: 客户要计算好多次,他想知道每次调用不同功能耗时多少(业务场景复杂了,有时候功能就能跑好几个小时!)
于是, 你做了这样的改动:
import time
def func1(x, y=10):
_start = time.time()
print(x + y)
end = time.time()
interval = end - _start
print("花费时间{}秒".format(interval))
def func2(x, y=10):
_start = time.time()
print(x * y)
end = time.time()
interval = end - _start
print("花费时间{}秒".format(interval))
def func3(x, y=10):
_start = time.time()
print(x // y)
end = time.time()
interval = end - _start
print("花费时间{}秒".format(interval))
def func4(x, y=10):
_start = time.time()
print(x % y)
end = time.time()
interval = end - _start
print("花费时间{}秒".format(interval))
func1(10, 30)
func2(10, 30)
func3(20)
func4(10)
看起来和套娃一样,如果有几百个功能,或者函数里面嵌套函数,那么..好痛苦呀,开始违背python初衷了,别提再删除了,万一眼花删了其他函数
于是, 优美简洁又好删的装饰器出现了
import time
# 定义装饰器
def timer(function):
def decora(*args, **kwargs):
_start = time.time()
function(*args, **kwargs) # 要运行的功能,都带参数,用 *args 和 **kwargs 接收任意数量的位置参数和关键字参数
end = time.time()
interval = end - _start
print("花费时间{}秒".format(interval))
return decora
@timer # 使用装饰器
def func1(x, y=10):
print(x + y)
@timer
def func2(x, y=10):
print(x * y)
@timer
def func3(x, y=10):
print(x // y)
# @timer # 不使用装饰器
def func4(x, y=10):
print(x % y)
func1(10, 30)
func2(10, 30)
func3(20)
func4(10)
@timer就相当于funX = timer(funX),函数funX作为参数传递给timer,随后将其返回值return给decra(判断:缩进).
故而,当调用被装饰的函数时,即执行了一遍decora函数,同时实现自己与计时的功能.