[英]Why is singleton class' __init__() method called twice?
为什么foo
被打印两次?
class A:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, *, var):
print('foo')
self.var = var
a = A(var=1)
b = A(var=2)
assert a == b
assert a.var == b.var
当您编写A(...)
时,您正在调用
type.__call__(A, ...)
那是因为type
是A
的元类。 type.__call__
将依次调用__new__
和__init__
。 如果__new__
返回 class 的实例,则将始终调用__init__
。 这是一个简化的视图:
def __call__(cls, *args, **kwargs):
self = cls.__new__(cls, *args, **kwargs)
if isinstance(self, cls):
cls.__init__(self, *args, **kwargs)
return self
我能想到的让 singleton 以这种方式工作的最简单方法是将所有初始化逻辑放入__new__
:
class A:
_instance = None
def __new__(cls, *, var):
if cls._instance is None:
self = super().__new__(cls)
self.var = var
cls._instance = self
return cls._instance
def __init__(self, *args, **kwargs):
print('foo')
当然,每次你请求一个新实例时, foo
仍然会被打印出来,但它确实是一个 singleton。
更全面的方法是覆盖元类__call__
方法的行为。 这将避免调用__init__
除了一次:
class Singleton(type):
def __call__(cls, *args, **kwargs):
if hasattr(cls, '_instance'):
return cls._instance
return super().__call__(*args, **kwargs)
class A(metaclass=Singleton):
def __init__(self, *, var):
print('foo')
self.var = var
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.