Python中单例模式__new__函数执行顺序详解

有两个类 A、B 均为单例,B 继承 A。实例化 B 时发现会先执行 B 的__new__函数,然后再执行 A 的__new__函数,请问各位大佬这是为什么?


class A(object):

_instance = None

def new(cls, *args, **kw):
if not cls._instance:

print ‘create A instance’

cls._instance = super(A, cls).new(cls, *args, **kw)

else:

print ‘instance A exists’

return cls._instance


def init(self):
print ‘A’

class B(A):
_instance = None
def new(cls,*args,**kw):
if not cls._instance:

print ‘create B instance’

cls._instance = super(B, cls).new(cls, *args, **kw)
else:

print ‘instance B exists’

return cls._instance

def init(self):
print ‘B’

b1=B()

输出为:
create B instance
create A instance
B
Python中单例模式__new__函数执行顺序详解


6 回复

Python3 下没输出 B, 不太懂,也想知道为什么。


在Python里用__new__实现单例,执行顺序其实挺直接的。__new____init__之前调用,它是真正创建实例的方法。看这段代码就明白了:

class Singleton:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            print("创建新实例")
            cls._instance = super().__new__(cls)
        else:
            print("返回已有实例")
        return cls._instance
    
    def __init__(self, value):
        print(f"初始化实例,值为: {value}")
        self.value = value

# 测试
s1 = Singleton(10)  # 输出:创建新实例 → 初始化实例,值为: 10
s2 = Singleton(20)  # 输出:返回已有实例 → 初始化实例,值为: 20

print(s1 is s2)      # True
print(s1.value)      # 20(注意:这里被重新初始化为20了)

执行流程是这样的:

  1. 首次创建Singleton(10)时,__new__检查_instanceNone,于是调用父类的__new__创建新对象,赋值给_instance,然后返回
  2. 接着自动调用__init__(10)进行初始化
  3. 第二次创建Singleton(20)时,__new__发现_instance已存在,直接返回这个实例
  4. __init__(20)仍然会被调用,这会覆盖第一次的value

这里有个关键点:__init__每次都会执行,即使返回的是已有实例。所以单例模式下,如果__init__中有状态设置,可能会被意外覆盖。如果不想这样,可以在__new__里加个标志位控制__init__的执行,或者用元类实现更干净的单例。

总结:__new__管创建,__init__管初始化,单例的核心是在__new__里控制实例的唯一性。

执行顺序没问题啊,你认为应该什么顺序呢。Python3 下没输出 B 是因为你的__new__函数创建实例后没有将实例返回,将后面 else 中的 return 减少一个缩进就可以了。

我的是 2.7 环境,会输出 B

困惑的地方有两点:1、为什么会生成 A 的实例? 2、B 是继承于 A,为什么不是先生成 A 的实例然后生成 B 的实例?

对于第二个问题,在 B 继承与 A 的情况下,当然是先创建 B,然后在创建 B 的过程中完成创建 A 的所有步骤再继续完成创建 B

回到顶部