我试图为我的一组不可变类处理符号表达式的记忆系统。到目前为止,我得到的如下。我不喜欢的是我不能直接阻止对__init__
的调用,并且必须将一些东西塞进对象(new_inst
属性)以跟踪__init__
方法是否应该做任何事情。有没有更蟒化的方法?
(new_inst
参数只是我告诉__new__
是否"停止"对__init__
的调用的一种简单方法。在现实中,这将基于对象是否已经存在于对象缓存中,并且不会是__new__
或__init__
的参数。
my_cache = {}
class Base(object):
def __new__(cls, *args, **kwargs):
signature = (cls, args)
if signature in my_cache:
self = my_cache[signature]
self.new_inst = True
else:
self = object.__new__(cls, *args, **kwargs)
my_cache[signature] = self
self.new_inst = False
return self
class A(Base):
def __init__(self, a):
if not self.new_inst:
print "Initializing A object with a=%d"%(a,)
self.a = a
class B(Base):
def __init__(self, a, b):
if not self.new_inst:
print "Initializing B object with a=%d, b=%d"%(a,b)
self.a = a
self.b = b
a1 = A(1)
a2 = A(1)
a3 = A(3)
b1 = B(1, 2)
b2 = B(1, 2)
b3 = B(1, 3)
print id(a1), id(a2), id(a3)
print id(b1), id(b2), id(b3)
输出:Initializing A object with a=1
Initializing A object with a=3
Initializing B object with a=1, b=2
Initializing B object with a=1, b=3
140246850102904 140246850102904 140246850102960
140246850103016 140246850103016 140246850103072
编辑:显然我没有弄清楚我在说什么,所以这里有一个更具体的例子。如您所见,第二个A(1)不会引起第二次初始化,它返回相同的id。
Base的简写new
def __new__(cls, *args, **kwargs):
signature = (cls, args)
new_inst = signature in my_cache
self = my_cache.get(signature, object.__new__(cls, *args, **kwargs))
self.new_inst = new_inst
return self
这并没有节省太多的处理时间,但它更简洁,更python化。我还没有见过一种更简洁的方法来检测新实例并在分配后设置它。