python装饰器
省流:直接看最后
从简单的例子开始,定义装饰器register,定义一个简单的类method,使用装饰器装饰类
1 |
|
当import这个文件或者执行这个文件时,相当于执行了: 1
method = register('hello', name='name')(method)
这一步分开来看就是: 1
2tmp1 = register('hello', name='name')
method = tmp1(method)
tmp1是一个函数,就是register返回的warpper,然后调用tmp1,参数是类名,返回类本身。
这个执行是在定义类时执行的,并不是实例化时执行的。
比如执行上述代码输出: 1
2('hello',) name
warpper cls
如果装饰器调用时没参数,那就自动传入类名作为参数。比如:
1
2
3
4
5
6
7
8
9
10
11def register(*args, name=None):
def warpper(method_cls):
print('warpper cls')
return method_cls
print(args, name)
return warpper
@register
class method:
def __init__(self):
print('__init__ method class')
输出就是: 1
(<class '__main__.method'>,) None
注意:这里将类作为register的参数,相当于 1
method = register(method)
这时,再实例化method类,就会导致报错:代码添加 1
method()
输出: 1
2
3
4
5(<class '__main__.method'>,) None
Traceback (most recent call last):
File "decorators.py", line 15, in <module>
method()
TypeError: warpper() missing 1 required positional argument: 'method_cls'
warpper缺少参数!这说明调用method()时,已经是在调用warpper()了
省流:
进行到这一步,可以总结了:
假设写了一句 1
2
3@xxx
class abc:
...
实际执行的就是: 1
abc = xxx(abc)
如果你写的是@xxx(balabala),那就是abc = xxx(balabala)(abc)