Python单例模式懒实例化相关问题:isinstance判断与__init__调用异常
Python单例模式实现问题解答
问题1解答
1.1 为什么isinstance(x, Singleton1)返回True
当执行x = Singleton1()时,Python的实例化流程是先调用父类object的__new__方法生成一个全新的Singleton1类实例,再将该实例传入__init__方法执行初始化逻辑。无论__init__内部的判断逻辑是什么,都不会改变已经创建完成的实例所属类,因此isinstance判断必然返回True。
你看到的打印内容是错误逻辑的输出:双下划线开头的类属性会触发Python的名称修饰机制,类属性__instance会被自动重命名为_Singleton1__instance,因此hasattr(Singleton1, '__instance')永远返回False,不代表实例没有被创建。
1.2 为什么叫懒实例化,是否还需要调用get_instance
懒实例化的核心定义是:全局唯一的单例实例只会在第一次需要使用时创建,不会在类加载阶段提前初始化。你的实现中__instance初始值为None,只有第一次调用get_instance方法时才会给__instance赋值为实例对象,符合懒加载的特征。
必须调用get_instance才能拿到全局唯一的单例:你没有重写__new__方法也没有私有化构造函数,直接调用Singleton1()每次都会生成全新的实例,完全不符合单例要求,只有通过get_instance返回的才是同一个全局实例。
问题2解答
2.1 __init__逻辑异常的原因
问题出在判断条件设计错误:你定义Singleton2类的时候已经显式给_instance赋值为None,因此hasattr(Singleton2, '_instance')永远返回True(属性确实存在,只是值为None)。
当你执行y = Singleton2()时,if not hasattr(Singleton2, '_instance')条件不成立,直接走else分支,打印当前_instance的值也就是None,和预期逻辑完全不符。
正确的判断逻辑应该是直接判断属性的值是否为None,而不是判断属性是否存在:
# 正确判断示例 @classmethod def get_instance(cls): if cls._instance is None: cls._instance = Singleton2() return cls._instance
如果要禁止外部直接调用构造函数生成多实例,你还需要重写__new__方法或者在__init__里抛出异常做限制。
内容的提问来源于stack exchange,提问作者showkey
相关产品推荐
相关产品推荐

