python版本:
python3 --version
Python 3.9.2
Issue 1:isinstance
function是什么意思?
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
上执行的名称混淆而变得复杂。一般来说,除了避免类层次结构中的名称冲突外,请避免使用双下划线的变量名。