Assigning to self

Peter Otten __peter__ at web.de
Mon Jan 17 14:02:45 EST 2005


Frans Englich wrote:

> What the code attempts to do is implementing a, to the API user,
> transparent memory-saver by ensuring that no more than one instance of the
> class foo exists for a particular id. E.g, the user can simply "create" an
> instance and if one not already exists, it is created.

By the time __init__() is called, a new Foo instance has already been
created. Therefore you need to implement Foo.__new__().  E. g.:

>>> class Foo(object):
...     cache = {}
...     def __new__(cls, id):
...             try:
...                     return cls.cache[id]
...             except KeyError:
...                     pass
...             cls.cache[id] = result = object.__new__(cls, id)
...             return result
...     def __init__(self, id):
...             self.id = id
...     def __repr__(self):
...             return "Foo(id=%r)" % self.id
...
>>> foos = map(Foo, "abca")
>>> foos
[Foo(id='a'), Foo(id='b'), Foo(id='c'), Foo(id='a')]
>>> foos[0] is foos[-1]
True
>>> Foo.cache
{'a': Foo(id='a'), 'c': Foo(id='c'), 'b': Foo(id='b')}

Note that putting the instances into the cache prevents them from being
garbage collected -- you may even end up with higher memory usage. 
Use a weakref.WeakValueDictionary instead of the normal dict to fix that.

Peter





More information about the Python-list mailing list