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 -- http://mail.python.org/mailman/listinfo/python-list