Python 函数装饰器 - 菜鸟教程
https://www.runoob.com/w3cnote/python-func-decorators.html
参考:https://eastlakeside.gitbook.io/interpy-zh/decorators/(与本文完全一致)
一切皆对象
在函数中定义函数
从函数中返回函数
将函数作为参数传给另一个函数
你的第一个装饰器
装饰器让你在一个函数的前后去执行代码。
装饰器封装一个函数,并且用这样或者那样的方式来修改它的行为。
@ 符号?那只是一个简短的方式来生成一个被装饰的函数。
使用functools.wraps还原被重写了被装饰函数的名字和注释文档(docstring)
from functools import wraps
@wraps(a_func)
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。
使用场景
授权(Authorization)
装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中。
日志(Logging)
带参数的装饰器
在函数中嵌入装饰器
装饰器类
装饰器 - 廖雪峰
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584
现在,假设我们要增强now()
函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()
函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
本质上,decorator就是一个返回函数的高阶函数。所以,我们要定义一个能打印日志的decorator,可以定义如下:
1 | def log(func): |
log()
是一个decorator,接受一个函数作为参数,并返回一个函数。
decorator用法:
1 | @log |
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:
1 | def log(text): |
这个3层嵌套的decorator用法如下:
1 | @log('execute') |
__name__
属性变化
1 | import functools |
或者针对带参数的decorator:
1 | import functools |
lru_cache 装饰器
https://juejin.cn/post/6939345971042058248
这里的lru_cache是什么意思和作用?*args为什么带星号
1 | @lru_cache(maxsize=128) |
lru_cache
是Python标准库中的一个装饰器,用于实现缓存功能。它可以缓存函数的返回值,以便在后续的调用中避免重新计算相同的输入值所对应的结果。这有助于提高函数的执行效率,特别是在需要计算代价较高的操作时。
具体来说:
lru_cache
是Least Recently Used(LRU,最近最少使用)缓存的缩写,它会保留最近调用的函数的结果,并在缓存达到指定大小(由maxsize
参数指定)时,自动淘汰最不常使用的结果,以保持缓存的大小。maxsize
参数指定缓存的最大大小,即最多保存多少个不同输入值的结果。如果没有指定maxsize
,则缓存的大小会无限增长。- 当函数被装饰为
@lru_cache(maxsize=128)
时,函数的每个不同的参数组合(传递给*args
的值)都会被缓存,以及它们对应的返回值。下次再次使用相同的参数调用函数时,如果参数组合已经在缓存中,函数不会再次执行,而是直接返回之前的结果。 - 这里的
*args
是Python中的可变参数,它允许函数接受任意数量的位置参数。在get_conf
函数中,*args
表示接受任意数量的参数,这些参数将被传递到read_single_conf_with_lru_cache
函数中。*
用于解包参数,因为args
是一个元组,*args
会将元组中的每个元素作为单独的参数传递给函数。
总结:@lru_cache
用于缓存函数的计算结果,*args
用于接受任意数量的输入参数,并将它们传递给被装饰的函数。这可以提高函数的执行效率,特别是在需要多次调用相同参数的情况下。