MST

星途 面试题库

面试题:Python类魔法方法之__init__与__new__

请解释Python类中__init__和__new__魔法方法的区别与联系,并举例说明在什么场景下会重写__new__方法。
36.4万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

区别

  1. 调用时机
    • __new__是在实例创建之前被调用,它的任务是创建并返回一个实例对象。
    • __init__是在实例创建之后被调用,用于对新创建的实例进行初始化操作。
  2. 参数
    • __new__第一个参数是类本身(通常命名为cls),后续参数是传递给类构造函数的参数。
    • __init__第一个参数是实例对象本身(通常命名为self),后续参数同样是传递给类构造函数的参数。
  3. 返回值
    • __new__必须返回一个实例对象(通常是通过调用super().__new__(cls)得到),如果不返回实例对象,__init__不会被调用。
    • __init__不需要返回值(实际上默认返回None)。

联系

__new__创建实例对象后,会将该对象作为self参数传递给__init__方法,以便进行初始化操作。

重写__new__方法的场景举例

  1. 实现单例模式
class Singleton:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance
    def __init__(self):
        pass


a = Singleton()
b = Singleton()
print(a is b)  

在这个例子中,通过重写__new__方法,确保无论创建多少次实例,都返回同一个实例对象,实现了单例模式。因为__new__方法只在第一次创建实例时真正创建对象,后续创建时直接返回已有的实例。 2. 创建不可变实例

class ImmutableClass:
    def __new__(cls, value):
        instance = super().__new__(cls)
        instance.value = value
        return instance
    def __init__(self, value):
        pass
    def __setattr__(self, name, value):
        raise AttributeError("This instance is immutable")


obj = ImmutableClass(10)
try:
    obj.value = 20
except AttributeError as e:
    print(e)  

这里重写__new__方法在创建实例时就设置好属性值,同时通过重写__setattr__方法禁止对实例属性的修改,达到实例不可变的目的。