1
__call__
和 __new__
是 Python 中的两个特殊方法,它们各自在 Python 的对象生命周期中扮演着重要的角色。
__call__
方法:
__call__
方法允许一个类的实例像函数一样被调用。当你尝试调用一个对象(即,在对象后面加上括号并传入参数)时,Python 会自动查找该对象的 __call__
方法并调用它。如果对象没有定义 __call__
方法,那么尝试调用对象将会引发一个 TypeError
。
示例:
class CallableClass:
def __call__(self, *args, **kwargs):
print("Instance is being called with", args, kwargs)
obj = CallableClass()
obj(1, 2, 3, a=4, b=5) # 输出: Instance is being called with (1, 2, 3) {'a': 4, 'b': 5}
在这个例子中,CallableClass
的实例 obj
被当作函数一样调用,并且传入了参数。Python 会自动查找并调用 obj
的 __call__
方法,并将传入的参数传递给这个方法。
__new__
方法:
__new__
方法是一个静态方法,它在 Python 的对象创建过程中比 __init__
更早被调用。__new__
方法负责创建并返回一个新对象,而 __init__
方法则负责初始化这个新创建的对象的状态。在大多数情况下,你不需要重写 __new__
方法,因为 Python 的默认实现已经足够用了。但在某些特殊情况下,比如当你需要控制对象的创建过程时,你可能需要重写它。
示例:
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating a new instance of MyClass")
instance = super().__new__(cls) # 调用父类的 __new__ 方法创建对象
print("New instance created")
return instance
def __init__(self, value):
print("Initializing the instance")
self.value = value
obj = MyClass(10) # 输出: Creating a new instance of MyClass, New instance created, Initializing the instance
在这个例子中,当创建 MyClass
的一个新实例时,__new__
方法首先被调用,负责创建对象。然后,__init__
方法被调用,负责初始化这个新创建的对象的状态。注意,在 __new__
方法中,我们使用 super().__new__(cls)
来调用父类的 __new__
方法创建对象。这是因为 __new__
方法是一个静态方法,它不像 __init__
方法那样自动接收类作为第一个参数。因此,我们需要显式地传递类 cls
给 super().__new__
。
2
在 Python 中,__new__
方法不会直接调用 __call__
方法。这两个方法具有不同的目的和调用时机,它们在对象的生命周期中扮演着不同的角色。
__new__
是一个静态方法,它在对象实例化时最先被调用,用于创建并返回对象实例。它的主要作用是控制对象的创建过程,例如,当你需要自定义对象的创建逻辑时,你可以重写 __new__
方法。__new__
方法在创建对象实例之后,通常会调用父类的 __new__
方法(通过 super().__new__(cls)
)来实际完成对象的创建。
一旦对象实例被创建,Python 会自动调用该实例的 __init__
方法来进行初始化。__init__
方法负责设置实例的初始状态,比如设置实例的属性等。
__call__
方法则允许类的实例像函数一样被调用。它在你尝试调用一个对象实例时(即在实例后面加上括号并传入参数)被自动调用。如果你没有定义 __call__
方法,并且尝试调用对象实例,将会引发一个 TypeError
。
因此,__new__
和 __call__
在对象生命周期中处于不同的阶段,它们不会互相调用。__new__
用于创建对象实例,而 __call__
用于使对象实例能够像函数一样被调用。它们各自有各自的作用和用途,是 Python 中面向对象编程的重要组成部分。
实际上,对象的实例化并不直接通过
__call__
方法来完成。对象的实例化是通过调用类的构造器来完成的,这通常涉及到
__new__
和__init__
方法,而不是__call__
。在 Python 中,当你使用类名加上括号和参数来创建一个新的对象实例时,Python 首先调用类的
__new__
方法来创建这个实例。__new__
方法负责返回一个新的对象实例,但并不负责初始化这个实例的状态。一旦
__new__
方法返回了一个新的对象实例,Python 会自动调用这个实例的__init__
方法来进行初始化。__init__
方法接收__new__
方法返回的对象实例作为它的第一个参数(通常命名为
self
),并可以接收其他参数来设置对象的初始状态。
__call__
方法与对象的实例化是不同的概念。__call__
方法允许类的实例像函数一样被调用。当你尝试调用一个对象实例(即,在实例后面加上括号并传入参数)时,Python 会自动查找该实例的
__call__
方法并调用它。这通常用于实现可调用对象,比如函数式编程中的高阶函数或者自定义的可调用类。因此,对象的实例化是通过
__new__
和__init__
方法来完成的,而不是通过__call__
。__call__
方法是在对象实例已经被创建并初始化之后,用于使对象实例能够像函数一样被调用的。这两个过程在 Python 的对象生命周期中是分开的。