你可能知道如何在Python中使用函数创建装饰器。在这篇文章中,我们将讨论在Python中使用类来创建装饰器的方法。首先我们将讨论什么是可调用对象,然后我们将通过定义类来实现使用这些可调用对象的装饰器。
什么是可调用对象?
python中任何可以像函数和方法一样被调用的对象都被称为可调用对象。在 python 中,每个可调用对象在其类定义中都有__call__() 方法的实现。我们可以说,任何在其类定义中具有 调用__() 方法的对象都被称为可调用对象。
要调用一个对象,我们需要实现 呼叫对象()方法在该对象的类定义中。
例如,请看下面的源代码。
class Car:
def __init__(self):
self.brand = "Tesla"
self.speed = "100mph"
def __call__(self, *args, **kwargs):
print("Called me? I am coming at {} speed.".format(self.speed))
在这里,我们定义了一个名为 汽车.除了它的构造函数定义外,我们还在它的类定义中定义了 __call__()方法。现在我们可以调用该类的任何实例 轿车类的任何实例,并且 __call__()方法将被执行,如下所示。
class Car:
def __init__(self):
self.brand = "Tesla"
self.speed = "100mph"
def __call__(self, *args, **kwargs):
print("Called me? I am coming at {} speed.".format(self.speed))
# create callable object
myCar = Car()
# call myCar
myCar()
输出
Called me? I am coming at 100mph speed.
我们可以使用任何接受函数或可调用对象作为输入并返回可调用对象或函数的可调用对象来实现python装饰器。
如何使用类来创建装饰器?
我们可以通过使用__call__()方法定义可调用对象来使用类创建装饰器,我们将在本节中讨论。
首先,我们将定义一个函数 添加(),将两个数字作为输入并打印出它们的总和。
def add(num1, num2):
value = num1 + num2
print("The sum of {} and {} is {}.".format(num1, num2, value))
# execute
add(10, 20)
输出
The sum of 10 and 20 is 30.
现在,我们必须定义一个装饰器,以使 添加()函数也应该打印两个数字的乘积和总和。为此,我们可以创建一个装饰器类。
我们可以在一个类中实现 __call__()方法在一个类中实现装饰器。
首先,我们将定义decorator_class的构造函数,接受 添加()函数作为输入参数,并将其分配给一个类变量 乐趣.
然后,我们将实现 呼叫()方法。()方法中的代码 呼叫()方法中的代码将计算输入数字的乘积并将其打印出来。之后,它将用给定的输入数字调用输入函数add()。最后,它将返回由add()函数返回的值。
class decorator_class:
def __init__(self, func):
self.func = func
def __call__(self, *args):
product = args[0] * args[1]
print("Product of {} and {} is {} ".format(args[0], args[1], product))
return self.func(args[0], args[1])
在这个 呼叫()方法中,我们已经实现了打印输入数字的乘积的代码,并在调用后返回 添加()函数的输出。该 添加(由于我们已经定义了函数和装饰器类,让我们看看如何使用它们。
通过将函数作为参数传递给类构造函数来创建装饰器
要创建一个装饰函数,我们可以将 添加()函数作为输入参数传递给装饰器类的构造函数。该 添加()函数将被分配给 函数中的变量。 decorator_class.一旦一个()的实例被调用,它将执行()中的代码。 装饰器类的实例被调用,它将执行 呼叫()方法来打印输入数字的乘积。然后,它将返回函数的输出 趣事调用后返回函数的输出。由于 加()函数已被分配给 乐趣,它将打印数字的总和。
class decorator_class:
def __init__(self, func):
self.func = func
def __call__(self, *args):
product = args[0] * args[1]
print("Product of {} and {} is {} ".format(args[0], args[1], product))
return self.func(args[0], args[1])
def add(num1, num2):
value = num1 + num2
print("The sum of {} and {} is {}.".format(num1, num2, value))
# execute
decorator_object = decorator_class(add)
decorator_object(10, 20)
输出
Product of 10 and 20 is 200
The sum of 10 and 20 is 30.
通过使用@符号创建装饰器
我们可以在类的构造函数中不传递add函数,而是指定 decorator_class()函数的定义前,用**@**符号指定 添加()函数。此后,每当 添加()函数被调用时,它就会同时打印输入数字的乘积和总和。
class decorator_class:
def __init__(self, func):
self.func = func
def __call__(self, *args):
product = args[0] * args[1]
print("Product of {} and {} is {} ".format(args[0], args[1], product))
return self.func(args[0], args[1])
@decorator_class
def add(num1, num2):
value = num1 + num2
print("The sum of {} and {} is {}.".format(num1, num2, value))
# execute
add(10, 20)
输出
Product of 10 and 20 is 200
The sum of 10 and 20 is 30.
在这种方法中,有一个缺点,你不能用 添加()函数在使用@符号定义装饰函数时,不能只是将数字相加。它将总是打印数字的乘积和它们的总和。所以,如果你在任何其他地方使用add()函数的原始形式,它将导致一个错误。
总结
在这篇文章中,我们已经讨论了在Python中使用类来创建Python装饰器的方法。