2024-简单点-python中的__call__和__new__和__init__

1

__call____new__ 是 Python 中的两个特殊方法,它们各自在 Python 的对象生命周期中扮演着重要的角色。

  1. __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__ 方法,并将传入的参数传递给这个方法。

  1. __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__ 方法那样自动接收类作为第一个参数。因此,我们需要显式地传递类 clssuper().__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 的对象生命周期中是分开的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万物琴弦光锥之外

给个0.1,恭喜老板发财

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值