You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python单例模式代码执行结果不符合预期?

单例模式下实例属性被覆盖的原因分析

问题描述

我用Python实现了Singleton(单例)设计模式,预期先初始化的实例b的number值在4-33区间,后初始化的实例a的number值在100-200区间,但实际输出两者数值相同(比如148 148)。代码如下:

import random

class Rng:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Rng, cls).__new__(cls)
        return cls._instance

    def __init__(self, a, b):
        self.number = random.randint(a, b)

b = Rng(4, 33)
a = Rng(100, 200)
print(a.number , b.number)

输出结果:

output: 148 148

原因解释

你实现的单例模式保证了整个程序中只会存在一个Rng类的实例,问题出在Python的实例创建流程上:

  • 第一次调用Rng(4,33)时,__new__方法检测到_instance为空,创建了第一个实例;紧接着__init__方法执行,给这个实例的number赋值为4-33之间的随机数。
  • 第二次调用Rng(100,200)时,__new__方法直接返回已经存在的那个实例,但**__init__方法会再次被调用**,把这个唯一实例的number重新赋值为100-200之间的随机数。
  • 变量a和b其实指向的是同一个对象,所以打印出来的number自然是最后一次__init__赋值的结果。

解决办法

方案1:仅首次创建实例时初始化属性

如果只需要单例实例的一个固定随机值,修改__init__逻辑,让它只在实例首次创建时执行初始化:

import random

class Rng:
    _instance = None
    _initialized = False

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Rng, cls).__new__(cls)
        return cls._instance

    def __init__(self, a, b):
        if not self._initialized:
            self.number = random.randint(a, b)
            self._initialized = True

b = Rng(4, 33)
a = Rng(100, 200)
print(a.number , b.number)  # 输出4-33之间的随机数,两次打印相同

方案2:存储不同参数对应的随机值

如果需要保留不同参数对应的随机值,同时维持单例,可以用字典存储参数与值的映射:

import random

class Rng:
    _instance = None
    _param_values = {}

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Rng, cls).__new__(cls)
        return cls._instance

    def __init__(self, a, b):
        param_key = (a, b)
        if param_key not in self._param_values:
            self._param_values[param_key] = random.randint(a, b)
        self.current_number = self._param_values[param_key]

b = Rng(4, 33)
a = Rng(100, 200)
print(a.current_number , b.current_number)  # 分别输出100-200和4-33的随机数

内容的提问来源于stack exchange,提问作者Emam Kownine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:23:33