已记忆的对象仍会调用其 __init__() 吗?
Memoized objects still have their __init__() invoked?
所以我正在创建一个记忆 class,并且一直在观察一个奇怪的行为。
这是代码片段:
class SomeClass(object):
_Memoized = {}
def __new__(cls, id: str, *args, **kwargs):
if id not in cls._Memoized:
print('New Instance')
cls._Memoized[id] = super(SomeClass, cls).__new__(cls, *args, **kwargs)
else:
print('Existing Instance')
return cls._Memoized[id]
def __init__(self, id: str):
print('Running init')
self.id = id
def test():
w1 = SomeClass(id='w1')
wx = SomeClass(id='w1')
print(id(w1), id(wx), id(w1) == id(wx))
test()
运行 上面的代码导致:
New Instance
Running init
Existing Instance
Running init <===-------------------???
140008534476784 140008534476784 True
我的问题:在第二次调用SomeClass()
时,为什么执行__init__
构造函数? __init__
构造函数不是只在实例化时调用吗?有没有办法阻止 __init__
被调用?
__new__
的目的是创建一个新实例,这就是 Python 在其上调用 __init__
的原因。您可以改写元类上的 __call__
以避免创建新实例。
class MemoMeta(type):
def __init__(self, name, bases, namespace):
super().__init__(name, bases, namespace)
self.cache = {}
def __call__(self, id_, *args, **kwargs):
if id_ not in self.cache:
print('New Instance')
self.cache[id_] = super().__call__(id_, *args, **kwargs)
else:
print('Existing Instance')
return self.cache[id_]
class SomeClass(metaclass=MemoMeta):
def __init__(self, id_, *args, **kwargs):
print('Running init')
self.id = id_
def test():
w1 = SomeClass(id_='w1')
wx = SomeClass(id_='w1')
print(id(w1), id(wx), id(w1) == id(wx))
test()
所以我正在创建一个记忆 class,并且一直在观察一个奇怪的行为。
这是代码片段:
class SomeClass(object):
_Memoized = {}
def __new__(cls, id: str, *args, **kwargs):
if id not in cls._Memoized:
print('New Instance')
cls._Memoized[id] = super(SomeClass, cls).__new__(cls, *args, **kwargs)
else:
print('Existing Instance')
return cls._Memoized[id]
def __init__(self, id: str):
print('Running init')
self.id = id
def test():
w1 = SomeClass(id='w1')
wx = SomeClass(id='w1')
print(id(w1), id(wx), id(w1) == id(wx))
test()
运行 上面的代码导致:
New Instance
Running init
Existing Instance
Running init <===-------------------???
140008534476784 140008534476784 True
我的问题:在第二次调用SomeClass()
时,为什么执行__init__
构造函数? __init__
构造函数不是只在实例化时调用吗?有没有办法阻止 __init__
被调用?
__new__
的目的是创建一个新实例,这就是 Python 在其上调用 __init__
的原因。您可以改写元类上的 __call__
以避免创建新实例。
class MemoMeta(type):
def __init__(self, name, bases, namespace):
super().__init__(name, bases, namespace)
self.cache = {}
def __call__(self, id_, *args, **kwargs):
if id_ not in self.cache:
print('New Instance')
self.cache[id_] = super().__call__(id_, *args, **kwargs)
else:
print('Existing Instance')
return self.cache[id_]
class SomeClass(metaclass=MemoMeta):
def __init__(self, id_, *args, **kwargs):
print('Running init')
self.id = id_
def test():
w1 = SomeClass(id_='w1')
wx = SomeClass(id_='w1')
print(id(w1), id(wx), id(w1) == id(wx))
test()