class Point(object): __cache = {} def __new__(cls, x, y): if (x, y) in Point.__cache: return Point.__cache[(x, y)] else: o = object.__new__(cls) ox = x oy = y Point.__cache[(x, y)] = o return o >>> Point(1, 2) <__main__.Point object at 0xb6f5d24c> >>> id(Point(1, 2)) == id(Point(1,2)) True
If you need a really simple class like Point , always consider collections.namedtuple
from collections import namedtuple def Point(x, y, _Point=namedtuple('Point', 'x y'), _cache={}): return _cache.setdefault((x, y), _Point(x, y)) >>> Point(1, 2) Point(x=1, y=2) >>> id(Point(1, 2)) == id(Point(1, 2)) True
I used the function next to namedtuple because it is a simpler IMO, but you can easily represent it as a class if necessary:
class Point(namedtuple('Point', 'x y')): __cache = {} def __new__(cls, x, y): return Point.__cache.setdefault((x, y), super(cls, Point).__new__(cls, x, y))
As @PetrViktorin pointed out in his answer, you should consider using weakref.WeakValueDictionary so that remote class instances (apparently don't work with namedtuple ) do not remain in memory since they are still referenced in the dictionary itself.