单例模式与继承覆盖问题:实例创建顺序引发属性异常
单例模式与多层继承的冲突问题
我在使用Singleton单例模式结合多层继承时碰到了问题:先创建slow_grizzly实例能得到预期结果,但如果先创建alaska_bear实例,后续创建的slow_grizzly的属性会完全被alaska_bear覆盖,我搞不懂这是为什么。
class Singleton(): __instance = None def __new__(cls, *args, **kwargs): if cls.__instance is None: cls.__instance = super().__new__(cls) return cls.__instance class Animal(Singleton): def __init__(self, *args, is_white=False, **kwargs): self.is_white = is_white class Bear(Animal): def __init__(self, region=None, *args, **kwargs): super().__init__(*args, **kwargs) self.region = region class Grizzly(Bear): def __init__(self, max_speed, *args, **kwargs): super().__init__(*args, **kwargs) self.max_speed = max_speed alaska_bear = Bear("Alaska") slow_grizzly = Grizzly(44, region="Colorado", is_white=False) print(alaska_bear.__dict__) #{'is_white': False, 'region': 'Alaska'} print(slow_grizzly.__dict__)#expected {'is_white': False, 'region': 'Colorado', 'max_speed': 44} #but got {'is_white': False, 'region': 'Alaska'}
问题根源
你写的单例模式存在核心缺陷:所有子类共享同一个实例。
Singleton基类中的__instance是属于Singleton自身的类属性,并非每个子类独立持有。当你首次创建Bear实例时,Singleton.__new__会将这个Bear对象存入Singleton.__instance。后续创建Grizzly实例时,__new__检测到Singleton.__instance已有值,直接返回这个已存在的Bear对象,而非创建新的Grizzly实例。
之后执行Grizzly.__init__时,所有属性修改都是在这个共享的Bear对象上进行的——哪怕你传入了新的region参数,最终也会因为单例共享导致属性被覆盖或混乱,出现你看到的不符合预期的结果。
修复方案
要让每个子类拥有独立的单例,需要将__instance绑定到子类自身的类属性上,而非基类。修改Singleton的__new__方法即可:
class Singleton(): def __new__(cls, *args, **kwargs): # 检查当前子类是否已创建过实例 if not hasattr(cls, '__instance'): cls.__instance = super().__new__(cls) return cls.__instance
修改后,Bear和Grizzly会各自维护自己的单例实例,创建过程互不干扰。运行代码后就能得到预期结果:
alaska_bear.__dict__输出:{'is_white': False, 'region': 'Alaska'}slow_grizzly.__dict__输出:{'is_white': False, 'region': 'Colorado', 'max_speed': 44}
内容的提问来源于stack exchange,提问作者Alexis
相关产品推荐
相关产品推荐

