Python 为什么是单身阶级'__调用了两次init_u;()方法?
为什么Python 为什么是单身阶级'__调用了两次init_u;()方法?,python,python-3.x,Python,Python 3.x,为什么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')
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
的元类<代码>类型.\uuuuuuuuuuuuu调用\uuuuuuu将依次调用\uuuuuuuu新建\uuuuuuuuuu
和\uuuuuuuuuuu初始化\uuuuuuuuuuu
<如果\uuuu new\uuuu
返回类的实例,则将始终调用code>\uuuu init\uuuu。以下是一个简化视图:
def __call__(cls, *args, **kwargs):
self = cls.__new__(cls, *args, **kwargs)
if isinstance(self, cls):
cls.__init__(self, *args, **kwargs)
return self
我能想到的最简单的方法是将所有初始化逻辑放入\uuuuu new\uuuu
:
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
仍然会在每次请求新实例时打印出来,但它确实是一个单例
更全面的方法是重写元类调用方法的行为。这将避免调用\uuuuu init\uuuuu
,除非调用一次:
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
因为每次调用
\uuuuu init\uuuuu
时,都会在\uuuu new\uuuu
之后调用。您使\uuuuuuuuuuuuuuuuu
返回同一个对象的事实并不会阻止\uuuuuuuuuuuuuuuuu
的执行。如果\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>将返回现有对象,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
应该是禁止操作的