装饰器基础
@意味着@下面定义的函数/类/方法是@后面函数的输入。例如以下两种方式是相等的:
@func
def x(a, b):
return f2
def func(f):
return f1(f)
def x(a, b):
return f2(a, b)
x = func(x)
@property
允许将类方法以类属性的形式调用,每次调用会单独进行一次计算:
class A(object):
def __init__(self,x):
self.x = x
@property
def add1(self):
return self.x + 1
a = A(1)
a.add1
@classmethod
可选构造函数或再次初始化
class A:
def __init__(self, x):
self.x = x
@classmethod
def from_subtract(cls, x1):
return cls(x1 - 1)
a = A.from_subtract(2)
在 init 之前构造类,参数 `cls` 类似 `self` ,但泛指整个该类,而不是一个实例对象。
@staticmethod
不需要 `self` 或 `cls`.
装饰器详解
@表示的装饰器具备如下特点:
- @后的函数后加括号时,等效于@该函数的返回值后不加括号
- 在解释的时候立即执行,不会等到显式调用
- 将被装饰函数替换为以该函数为输入的装饰函数的返回值
例子:
def decorator_factory(a):
print(f'decorator_factory: {a}')
def decorator(fn):
print('decorator')
def wrapper():
print("Before calling function")
fn()
print("After calling function")
return wrapper
return decorator
@decorator_factory(0314)
def my_function():
print("The function is called")
在这个例子中,@decorator_factory()等效于执行一遍decorator_factory后被替换为@decorator; 然后启动装饰执行一遍decorator(my_function)后将my_function替换为decorator的返回值,即wrapper,此时每次调用my_function,等同于调用wrapper。其输出为:
decorator_factory: 0314
decorator
如果执行
my_function()
则输出
Before calling function
The function is called
After calling function
如果没有@decorator_factory(),替换为@decorator可起到同样的效果,但此时decorator将没有自由参数a
如果没有wrapper则my_function将被替换为None,无法被再次调用,只在解释装饰器时执行一遍decorator(my_function)。