python中__init__真的会在__new__完成后执行吗?

前言

        在看书的过程中又发现了这个知识点盲区。有些东西不自己亲手去尝试,真的不会知道:居然是这样子的?

常规思路

        大家可能都知道,在python中创建一个对象的流程是:首先调用__new__方法创建一个实例,然后再调用__init__方法初始化这个实例对象。这个是常规的思路,也没有什么问题。

蹊跷的事情发生了!

        直接说结果吧:如果__new__方法返回的对象不是当前的类的实例,它就不会调用__init__方法。

        直接看下面的栗子吧(talk is cheap,show you the code.):

# __new__方法执行完成后不一定会调用__init__方法
# 只有当__new__方法返回的对象是当前类的实例时才会调用__init__方法
class A:
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)
        # return 'hello world!'

    def __init__(self):
        print('调用了__init__方法!')
a = A()

 

总结

        __init__方法只有在__new__方法返回的实例是当前类(祖先类)的实例的情况下才会被自动调用。

同步更新于个人博客系统:python中__init__真的会在__new__完成后执行吗?

### `__new__` 和 `__init__` 的区别 #### 作用与职责 `__new__` 是一个静态方法,负责创建类的实例对象。它在对象实例化过程中首先被调用,并返回一个实例。如果返回的不是当前类的实例,则不会调用 `__init__`[^4]。 `__init__` 是一个实例方法,用于初始化已被创建的对象实例。它在 `__new__` 返回实例后自动调用,通常用于设置对象的属性或执行初始化逻辑[^1]。 #### 调用顺序 `__new__` 在对象创建之前被调用,而 `__init__` 在对象创建之后被调用。两者的协作流程如下: 1. 当使用 `ClassName()` 实例化对象时,首先调用 `__new__` 创建实例。 2. 如果 `__new__` 返回的是当前类的实例,则继续调用 `__init__` 对该实例进行初始化[^3]。 #### 参数和返回值 `__new__` 接收的第一个参数是类本身(`cls`),随后可以接收任意数量的位置参数和关键字参数。它必须返回一个实例对象,通常是当前类的实例[^4]。 `__init__` 接收的第一个参数是实例对象(`self`),随后是与 `__new__` 相同的参数列表。它不返回任何值,若尝试返回非 `None` 值将引发异常[^4]。 #### 使用场景 `__new__` 通常用于需要控制对象创建过程的场景,例如单例模式、不可变类型子类化、对象池或缓存等[^4]。以下是一个实现单例模式的示例: ```python class Singleton: _instance = None def __new__(cls): if not cls._instance: cls._instance = super().__new__(cls) return cls._instance ``` `__init__` 更为常见,适用于大多数对象初始化需求,如设置属性、配置初始状态等。例如: ```python class Person: def __init__(self, name, age): self.name = name self.age = age ``` #### 注意事项 除非有特殊需求,否则应优先使用 `__init__`。重写 `__new__` 可能会影响对象创建的核心机制,容易引入难以调试的问题,因此需谨慎使用[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值