Python技术迷

__new__和__init__的区别

不得不说,Python这门语言,真是写着写着就容易掉坑。最近在复习一些面试题的时候,又翻到了那个让不少人一脸懵逼的魔法方法:__new__ 和 __init__。

你说__init__吧,大家都挺熟,毕竟天天写类的时候离不开它;但这__new__,啧,真是冷门得像是仓库里落灰的老配置,平时也不咋用,但偏偏在面试里总爱冒出来吓唬人。

行吧,今天咱就把这俩货捋一捋,顺便来点代码实践,看看它们到底有啥不同,别到时候面试官一问你就“emmm……”,那多尴尬。

先说__init__,这是个老朋友

简单点说,__init__就是初始化实例用的。比如:

classDog:
def__init__(self, name):
        print("Calling __init__")
        self.name = name

dog = Dog("Buddy")

这玩意儿谁没写过?实例化对象的时候,__init__就会自动调用,负责给这个对象设定一些初始状态,比如这儿给狗取了个名字。

但注意,__init__其实不负责创建实例,它只是给已经创建好的实例“打扮打扮”,设置点属性啥的。

再看__new__,这是真·冷门

__new__才是负责“制造”实例的那个家伙。它是在对象创建之前被调用,负责返回这个实例。说白了,你要是想控制实例的生成过程,就得用__new__出马。

来看个栗子:

classDog:
def__new__(cls, name):
        print("Calling __new__")
        instance = super().__new__(cls)
return instance

def__init__(self, name):
        print("Calling __init__")
        self.name = name

dog = Dog("Buddy")

运行结果:

Calling __new__
Calling __init__

是不是发现了?__new__先调用,负责返回一个实例,然后__init__才上去给它“装扮”。

这俩到底有啥区别?

  • __new__是个静态方法,专门负责创建实例,返回的就是这个实例对象。
  • __init__是个实例方法,专门负责初始化实例,啥也不返回,只是操作一下传进来的实例。
  • 如果__new__不返回一个实例,那__init__就不会被调用,毕竟没有对象可初始化,咋初始化?

而且,__new__一般只有在需要自定义元类(metaclass)或者做单例模式时才用得着。平时写类,基本靠__init__就够用了,__new__你可能几年都碰不到一回。

举个实际点的例子,单例模式

这个时候__new__就派上用场了,比如搞个单例模式,防止创建多个实例:

classSingleton:
    _instance = None

def__new__(cls, *args, **kwargs):
if cls._instance isNone:
            cls._instance = super().__new__(cls)
return cls._instance

def__init__(self, name):
        self.name = name

a = Singleton("A")
b = Singleton("B")

print(a is b)  # True
print(a.name)  # B

看到没?无论实例化多少次,a和b其实是同一个对象,这就是__new__的威力,专治实例重复。

那元类(metaclass)是啥?

元类是用来创建类的“类”。类是对象,对象有类,类自己也有类——这就是元类,通常是type。

如果你想在类创建时动点手脚,比如自动加点方法、属性啥的,就得靠元类。元类跟__new__、__init__分别负责类创建、实例创建、实例初始化三个阶段,分工明确,各司其职。

不过面试真问你元类,咱劝你一句:别慌,直接说“我平时用得不多,但知道它是用来控制类生成过程的”,别瞎扯,越扯越乱。

面试官问你:__new__ 和 __init__ 有啥区别?

最优回答:

`__new__`是一个静态方法,负责创建实例对象,它会返回这个实例;`__init__`是一个实例方法,用来初始化这个实例对象,不返回值。创建实例时,`__new__`先执行,返回实例后才会调用`__init__`。如果`__new__`返回的不是这个类的实例,`__init__`就不会被调用。一般情况下我们用`__init__`就够了,只有在需要控制实例生成过程时才会用到`__new__`,比如实现单例模式或者自定义元类。

这回答,既不啰嗦,又有重点,面试官听了估计得点头。要是再加一句:“平时基本用不到__new__,但知道它在对象创建过程中起作用”,就更稳了。

说实话,我觉得Python这些魔法方法设计得挺有意思,但有时候也是真绕。__init__天天用,__new__冷不丁冒出来,总得踩几次坑才记住。程序员这行,别怕坑,掉多了反而记得牢。

最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek

也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。

对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。

资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB,全部免费领取