Python __call__()方法

发布时间:2022-07-24

魔术方法介绍

以双下划线作为前缀和后缀的方法名是 Python 中特定使用的保留方法。例如,__init__ 方法用于对象构造器,或者 __call__ 方法用于使对象可调用。我们称这些方法为邓德方法,其中邓德指的是双 under(下划线)。这些邓德法又被称为魔法——然而,并没有什么神奇的与之相关。Python 社区中有许多开发人员不太喜欢“魔法”这个词,因为它给人一种不鼓励使用这种方法的感觉,但矛盾是事实。

理解可调用函数

当对象在 __call__() 函数中定义时,Python 中的对象被称为可调用的。相同的功能可以定义为 x(arg1, arg2, ...),这是 x.__call__(arg1, arg2, ...) 的缩写。

注意callable() 方法返回一个布尔值,该值表示对象是否看起来是可调用的。如果对象是可调用的,此函数返回 True;否则,它返回 False。此外,即使对象不可调用,该函数也可能返回 True。然而,如果这个方法返回 False,那么这个对象是不可调用的。 此外,Python 类总是可调用的。因此,我们总是可以将 callable() 函数用于类的对象,而不是类本身。 为了理解 Python callable() 函数的行为,让我们考虑以下示例。

示例:

# creating a class
class Employee:
    n = 0
    # defining a function
    def __init__(self, emp_id):
        self.i = emp_id
# instantiating the class
x = Employee(15)
# checking if the class and object are callable or not
print('Employee Class is callable = ', callable(Employee))
print('Employee object is callable = ', callable(x))

输出:

Employee Class is callable =  True
Employee object is callable =  False

说明:

在上面的例子中,我们定义了一个类 Employee,它接受一个变量 n = 0。然后我们定义了一个函数并实例化了这个类。最后,我们使用 callable() 函数检查了类及其对象是否可调用。 让我们考虑一个定义 __call__() 函数的例子。

示例:

# creating Person Class
class Person:
    person_id = 0
    person_name = ""
    # defining an initializing function
    def __init__(self, personid, personname):
        self.person_id = personid
        self.person_name = personname
    # defining a callable function
    def __call__(self, *args, **kwargs):
        print('Printing Arguments')
        print(*args)
        print('Printing Keyword Arguments')
        for key, value in kwargs.items():
            print("%s == %s" % (key, value))
# instantiating the class
m = Person(15, 'George')
# printing the object
print(m)
# checking if the object is callable or not
print("The Person object is callable: ", callable(m))

输出:

<__main__.Person object at 0x...>
The Person object is callable:  True

说明:

在上例中,我们定义了 Person 类和变量 person_id = 0person_name = ""。然后我们定义了初始化函数和可调用函数。最后,我们已经实例化了类,打印了对象,并检查了对象是否可调用。因此,person 对象看起来是可调用的。 此外,我们可以观察到,我们使用了 *args 来允许传递变量参数,**kwargs 来允许将命名参数传递给 __call__() 方法。 现在,让我们考虑另一个例子,我们将使用 callable() 函数来检查对象是否可调用,然后将对象作为函数调用。

示例:

if callable(m):
    m()
    m(15, 30)
    m.__call__(15, 30)
    m(15, 30, {'a': 4, 'b': 8})
    m(15, 'B', personname='George', personid=50)

输出:

Printing Arguments
Printing Keyword Arguments
Printing Arguments
15 30
Printing Keyword Arguments
Printing Arguments
15 30
Printing Keyword Arguments
Printing Arguments
15 30 {'a': 4, 'b': 8}
Printing Keyword Arguments
Printing Arguments
15 B
Printing Keyword Arguments
personname == George
personid == 50

说明:

在上面的例子中,我们定义了一个 if 语句,其中如果对象 m 是可调用的,那么该对象作为一个没有参数的函数被调用,只有参数,有 __call__() 函数,有不同类型的参数,有参数和关键字参数。因此,已成功调用了所需的对象。