,

python中单例模式

1. 单例模式 无参 super() 是语法糖,在 __new__ 里等价: super 会顺着 MRO 找下…

1. 单例模式

class DataBase:
    _instance = None

    def __new__(cls, *args, **keywords):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# 测试
conn1 = Database()
conn2 = Database()
print(conn1 is conn2)  # True,说明是同一个实例

无参 super() 是语法糖,在 __new__ 里等价:

super().__new__(cls)
# 等价完整写法
super(Database, cls).__new__(cls)

super 会顺着 MRO 找下一个父类(这里就是 object)。

__new__特殊的静态构造方法(内置特殊魔术方法,和普通实例方法 / 类方法规则不一样)

python 中所有类默认隐式继承 object,等价于:

class Database(object):

你不写父类,底层自动继承 object,所以一定存在父类,super() 完全合法。

super () 在 new 里的作用

super().__new__(cls) 等价于拿到父类 object__new__ 方法,调用底层内存分配逻辑,创建空实例对象。

  • 如果不写 super().__new__(cls),就没有对象,没法赋值给 _instance
  • object.__new__(Database) 才是真正分配内存、生成实例的底层方法。

对象的创建过程

当你写 obj = MyClass() 时,Python 内部执行流程分两步:

  1. 调用 MyClass.__new__(cls)
    • __new__ 负责分配内存、创建并返回空实例对象
    • 如果类没有自定义 __new__,会向上调用父类 object.__new__
  2. 拿到 __new__ 返回的实例后,调用 __init__(self) 做初始化赋值

类似于

def create_object(cls, *args, **kwargs):
    # 1. 调用 __new__ 创建实例
    obj = cls.__new__(cls, *args, **kwargs)

    # 2. 类型检查:只有 obj 是 cls 的实例(或其子类的实例)时才调用 __init__
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)

    # 3. 返回对象
    return obj

2. 对象池/缓存

class ConnectionPool:
    _pool = {}

    def __new__(cls, conn_id):
        if conn_id not in cls._pool:
            obj = super().__new__(cls)
            cls._pool[conn_id] = obj
        return cls._pool[conn_id]

# 测试
pool1 = ConnectionPool("conn_1")
pool2 = ConnectionPool("conn_1")
pool3 = ConnectionPool("conn_2")
print(pool1 is pool2)  # True,相同 conn_id 返回同一个对象
print(pool1 is pool3)  # False,不同 conn_id 返回不同对象

3. 正整数(带默认值回退)

__new__ 可以返回不同类型的对象。当返回的对象不是当前类的实例时,__init__ 不会被执行:

class PositiveInt:
   def __new__(cls, value):
       if value < 0:
           return 0  # 返回 int 类型的 0,不是 PositiveInt 的实例
       return super().__new__(cls)

   def __init__(self, value):
       print("PositiveInt.__init__ 被调用")
       self.value = value

# 测试
p = PositiveInt(5)
print(type(p))    # <class '__main__.PositiveInt'>
print(p.value)    # 5

n = PositiveInt(-3)
print(type(n))    # <class 'int'>
print(n)          # 0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor