问题描述
所以我正在创建一个记忆类,并且一直观察到一种奇怪的行为.
So I am creating a memoized class, and have been observing a strange behavior.
这是代码段:
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()
运行上面的代码将导致:
Running the above code results in:
New Instance
Running init
Existing Instance
Running init <===-------------------???
140008534476784 140008534476784 True
我的问题:在SomeClass()
的第二次调用期间,为什么要执行__init__
构造函数? __init__
构造函数不是仅在实例化时调用吗?有没有办法防止__init__
被调用?
My questions: During the second invocation of SomeClass()
, why does it execute the __init__
constructor? Wasn't the __init__
constructor only invoked on instantiating? Is there a way to prevent the __init__
from being invoked?
推荐答案
__new__
的目的是创建一个新实例,这就是Python在其上调用__init__
的原因.您可以改用元类上的__call__
以避免创建新实例.
The purpose of __new__
is to create a new instance, which is why Python calls __init__
on it. You might instead override __call__
on a metaclass to avoid creating a new instance.
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()
这篇关于记忆对象仍然调用了它们的__init __()吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!