单例模式中惰性实例化的两个问题
two issues on the lazy instantiation in the Singleton pattern
我的python版本:
python3 --version
Python 3.9.2
问题 1:
isinstance
函数是什么意思?
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的实例?
问题 2:
为什么无论如何都无法调用 __init__
方法?
现在将class中的所有__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
,因为 class 有一个名为 _instance
的属性。您想检查实例的 value,因此请改用 getattr;然后将打印预期的输出。
isinstance
检查成功,因为 Singleton2()
每次都会 return 一个新实例 - 没有什么可以阻止这一点。您可以添加一个 __new__
方法来在每次调用 Singleton2()
时创建 _instance
和 return 它。请注意,这意味着 _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
上执行的名称修改而变得复杂。一般来说,避免使用双下划线变量名,除非在 class 层次结构中避免名称冲突。
我的python版本:
python3 --version
Python 3.9.2
问题 1:
isinstance
函数是什么意思?
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的实例?
问题 2:
为什么无论如何都无法调用 __init__
方法?
现在将class中的所有__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
,因为 class 有一个名为 _instance
的属性。您想检查实例的 value,因此请改用 getattr;然后将打印预期的输出。
isinstance
检查成功,因为 Singleton2()
每次都会 return 一个新实例 - 没有什么可以阻止这一点。您可以添加一个 __new__
方法来在每次调用 Singleton2()
时创建 _instance
和 return 它。请注意,这意味着 _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
上执行的名称修改而变得复杂。一般来说,避免使用双下划线变量名,除非在 class 层次结构中避免名称冲突。