I'm trying to make a memoziation system for my set of immutable classes for handling symbolic expressions. What I've got so far is below. What I don't like is the fact that I can't block the call to __init__
directly and have to stuff something into the object (the new_inst
attribute) to track whether or not the __init__
method should do anything. Is there a more pythonic way of doing this?
(The new_inst
argument is just a simple way for me to tell __new__
whether to "stop" the call to __init__
or not. In reality this would be based on whether the object exists in the object cache already and wouldn't be a parameter to either __new__
or __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)
Output:
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
Edit: Apparently it wasn't clear what I was getting at, so here is a more concrete example. As you can see, the second A(1) doesn't cause a second initialization, and it returns the same id.