how to keep collection of existing instances and return one on instantiation
Peter Otten
__peter__ at web.de
Wed Oct 5 13:03:33 EDT 2005
marduk wrote:
> What I *really* want is to keep a collection of all the Spam instances,
> and if i try to create a new Spam instance with the same contructor
> parameters, then return the existing Spam instance. I thought new-style
> classes would do it:
>
> class Spam(object):
> cache = {}
> def __new__(cls, x):
> if cls.cache.has_key(x):
> return cls.cache[x]
On cache misses you implicitly return None. But your __init__() method will
only be called if __new__() returns a Spam instance.
> def __init__(self, x):
> self.x = x
> self.cache[x] = self
>
> a = Spam('foo')
> b = Spam('foo')
>
> Well, in this case a and b are identical... to None! I assume this is
> because the test in __new__ fails so it returns None, I need to then
> create a new Spam.. but how do I do that without calling __new__ again?
> I can't call __init__ because there's no self...
>
> So what is the best/preferred way to do this?
class Spam(object):
cache = {}
def __new__(cls, x):
try:
inst = cls.cache[x]
print "from cache"
except KeyError:
cls.cache[x] = inst = object.__new__(cls)
print "new instance"
return inst # always return a Spam instance
def __init__(self, x):
# put one-off initialization into __new__() because __init__()
# will be called with instances from cache hits, too.
print "init", x
a = Spam('foo')
b = Spam('foo')
print a, b, a is b
Peter
More information about the Python-list
mailing list