Python中的类装饰器
装饰器是Python中一个重要且有用的工具。它允许我们修改函数或类的行为。到目前为止,我们已经学会了如何使用函数创建装饰器,但是在这里我们将讨论如何定义一个类作为装饰器。在本教程中,我们将学习如何创建类装饰器。如果你对装饰器不熟悉,那么请从我们的Python装饰器教程中详细了解装饰器。
装饰器允许我们包装另一个函数,以扩展被包装函数的行为,而不对其进行永久性更改。
让我们看下面的示例。
示例
def pattern(n):
def decorate(fn):
def wrapper(*args, **kwargs):
print(n*'*')
result = fn(*args, **kwargs)
print(result)
print(n*'*')
return result
return wrapper
return decorate
@pattern(10)
def add(a, b):
return a + b
print(add(20, 30))
输出:
**********
50
**********
解释 –
在上面的代码中,我们创建了一个 star() 装饰器,它接受一个整数作为参数并返回一个可调用对象。可调用对象接受函数 func 作为参数,该函数将被装饰。另外,可调用对象可以从装饰器工厂中访问 n 。
现在我们将使用Python类来实现这个装饰器。
Python类装饰器
要定义类装饰器,我们需要使用类的 __call__() 方法。当我们需要创建一个行为像函数的对象时,函数装饰器必须返回一个行为像函数的对象。让我们看下面的示例来理解。
示例1:
class NewDocorator:
def __init__(self, function):
self.function = function
def __call__(self):
# can add some more code
self.function()
@NewDocorator
def function():
print("WelCome to JavaTpoint")
function()
输出:
WelCome to JavaTpoint
解释 –
我们使用类装饰器创建了一个简单的装饰器,使用 __call__ 方法。我们可以根据需要进行修改。现在,我们使用类装饰器重新编写上述代码。
示例2:
class Pattern:
def __init__(self, n):
self.n = n
def __call__(self, fn):
def wrapper(*args, **kwargs):
print(self.n*'*')
result = fn(*args, **kwargs)
print(result)
print(self.n*'*')
return result
return wrapper
@Pattern(5)
def add(a, b):
return a + b
add(20, 30)
输出:
*****
50
*****
解释 –
返回Pattern的实例,该实例是一个可调用的对象,因此它将按如下方式工作。
add = Pattern(5)(add)
使用返回语句的类装饰器
我们可以在类装饰器中使用返回语句。在前面的示例中,我们没有返回任何东西,所以没有问题。但有时候,我们需要返回一个值。我们可以像下面这样做。
示例
class CubeDecorator:
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
# before function
result = self.function(*args, **kwargs)
# after function
return result
# adding class decorator to the function
@CubeDecorator
def get_cube(n):
print("given number is:", n)
return n * n * n
print("Cube of number is:", get_cube(25))
输出:
Given number is: 25
Cube of number is: 15625
解释 –
在上述代码中,我们创建了一个名为 CubeDecorataor 的类作为装饰器,并调用了call()方法。在call()中,我们调用了调用者函数并返回结果。
使用类装饰器来打印程序的执行时间
我们使用time模块和call方法来获取程序的执行时间。让我们理解下面的示例。
示例
from time import time as t
from time import sleep
class Timer:
def __init__(self, func):
self.function = func
def __call__(self, *args, **kwargs):
start_time = t()
result = self.function(*args, **kwargs)
end_time = t()
print("Execution took {} seconds".format(end_time-start_time))
return result
# adding a decorator to the function
@Timer
def some_function(delay):
sleep(delay)
some_function(4)
输出:
Execution took 4.004076242446899 seconds
解释 –
我们从上面的代码中导入了time模块中的time方法,并将其命名为t。然后,我们创建了ExecutionTimer类作为一个装饰器,其中我们在程序开始执行时获取了开始时间,结束时获取了结束时间。我们将结束时间减去开始时间,得到了程序的执行时间。
总结
在本教程中,我们介绍了一些使用类装饰器的示例。装饰器是Python中的重要工具,可以改变另一个函数的行为,而不改变其实际实现。大多数情况下,我们使用Python函数来定义装饰器,但类装饰器也很有用,并且提高了代码的可读性。类装饰器可以作为参数扩展,如果没有传递参数,则返回默认值。