python 装饰器 decorators
装饰器解释
术语对照表:https://docs.python.org/zh-cn/3/glossary.html#term-decorator
decorator – 装饰器
返回值为另一个函数的函数,通常使用 @wrapper
语法形式来进行函数变换。 装饰器的常见例子包括 classmethod()
和 staticmethod()
。
装饰器语法只是一种语法糖,以下两个函数定义在语义上完全等价:
1 | def f(arg): |
同样的概念也适用于类,但通常较少这样使用。有关装饰器的详情可参见 函数定义 和 类定义 的文档。
chatgpt解释
Python装饰器是一种可以在不修改函数定义的情况下为函数添加额外功能的方法。装饰器是一种特殊类型的函数,它接收一个函数作为参数并返回一个新函数,新函数在原函数的基础上添加了额外的功能。装饰器的语法在 Python 中是通过 @ 语法实现的,例如:
1 |
|
装饰器可以用来给函数加入缓存、检查函数参数类型、记录函数调用日志等等。
装饰器详解
python里所有东西都是对象,函数也是对象。
- 因此函数也可以当作参数、变量(理解成是保存着函数对象的变量),传进其它函数里。
举例:
1 | def double(x): |
- 函数还可以成为一个返回值(函数的返回值可以是一个函数)
举例:
1 | def get_multiple_func(n): |
函数可被调用的,callable。装饰器是一个callable。
decorator是一个函数,写法是@
后面跟着的名字,就是函数名。
1 | def dec(f): |
多练习几遍这个写法加深记忆! double函数上面写一个@dec函数,其实完全等价于这样写:double = dec(double)
,输入是double函数,dec的输出传给double变量(函数)
decorator是一个输入和输出都是函数的函数(其实输出不一定是函数,极端情况故意不是函数(没意义),一般写法都是函数的)
举例:(这里先不用看args和kwargs)
1 | import time |
等价于 my_func = timeit(my_func) , 所以就是wrapper(1)传给左边my_func这个变量。
timeit函数当作decorator来用,输入f是一个函数,返回wrapper还是一个函数。
使用decorator好处:有不同函数时,都可以比较简洁的来完成这件事。
上述wrapper函数的初始形态为(补上args和kwargs):
1 | def timeit(f): |
args、kwargs作用:允许变长的函数参数 ,因此不管装饰的是什么函数,都能用这个装饰器。
还是以上面的例子为例,比如:
1 |
|
对于两个参数,装饰器timeit也能用。
带参数的decorator:相当于在等价的过程中,多了一次函数调用。
1 |
|
先计算timeit(10),返回一个函数,再用这个函数去调用double(传入double),再返回一个函数。
(之前不带参数的情况是:timeit(double),直接用timeit这个函数去调用double。)
举例:
1 | def timeit(iteration): |