关于Singleton模式中的延迟实例化的两个问题



python版本:

python3 --version
Python 3.9.2

Issue 1:
isinstancefunction是什么意思?

class Singleton1(object):
__instance = None
def __init__(self):
if not hasattr(Singleton1, '__instance'):
print("__init__ method called, but no instance created")
else:
print("instance already created:", self.__instance)
@classmethod
def get_instance(cls):
if not cls.__instance:
cls.__instance = Singleton1()
return cls.__instance

初始化:

x = Singleton1()
__init__ method called, but no instance created

检查isinstance功能:

isinstance(x,Singleton1)
True

如果x不是实例,为什么isinstance(x,Singleton1)说它是Singleton1的实例?

Issue2:
为什么不能调用__init__方法?

现在将Singleton1类中的所有__instance(双下划线)替换为_instance(单下划线),将所有Singleton1替换为Singleton2:

class Singleton2(object):
_instance = None
def __init__(self):
if not hasattr(Singleton2, '_instance'):
print("__init__ method called, but no instance created")
else:
print("instance already created:", self._instance)
@classmethod
def get_instance(cls):
if not cls._instance:
cls._instance = Singleton2()
return cls._instance

初始化:

y = Singleton2()
instance already created: None

为什么在这种状态下不能调用__init__方法?

@snakecharmerb on issue1,为什么有人说它是惰性实例化,如果isinstance(x,Singleton1)为真,则不需要调用Singleton1.get_instance(),因为实例在实例化过程中已经创建了。

hasattr检查并不像您想象的那样。使用Singleton2*hasattr(Singleton2, '_instance')总是True,因为该类有一个名为_instance的属性。你想检查实例的,所以使用getattr代替;然后输出预期的输出。

isinstance检查成功,因为Singleton2()每次都会返回一个新实例-没有什么可以阻止这一点。您可以添加一个__new__方法来创建_instance,并在每次调用Singleton2()时返回它。请注意,这将意味着_instance在调用__init__时将始终存在。

class Singleton2:
_instance = None     

def __new__(cls):    
if cls._instance is not None:    
return cls._instance    
instance = super().__new__(cls)    
cls._instance = instance    
return instance 

*Singleton1中的hasattr检查由于__instance上执行的名称混淆而变得复杂。一般来说,除了避免类层次结构中的名称冲突外,请避免使用双下划线的变量名。

相关内容

  • 没有找到相关文章