On Feb 8, 4:44 pm, Freek Dijkstra <[EMAIL PROTECTED]> wrote: > Is there a best practice on how to override __new__? > > I have a base class, RDFObject, which is instantiated using a unique > identifier (a URI in this case). If an object with a given identifier > already exists, I want to return the existing object, otherwise, I > want to create a new object and add this new object to a cache. I'm > not sure if there is a name for such a creature, but I've seen the > name MultiSingleton in the archive. > > This is not so hard; this can be done by overriding __new__(), as long > as I use a lock in case I want my code to be multi-threading > compatible. > > import threading > threadlock = threading.Lock() > > class RDFObject(object): > _cache = {} # class variable is shared among all RDFObject > instances > def __new__(cls, *args, **kargs): > assert len(args) >= 1 > uri = args[0] > if uri not in cls._cache: > threadlock.acquire() # thread lock > obj = object.__new__(cls) > cls._cache[uri] = obj > threadlock.release() # thread unlock. > return cls._cache[uri] > def __init__(self, uri): > pass > # ... > > However, I have the following problem: > The __init__-method is called every time you call RDFObject().
You need to override the __call__ method of the metaclass. By default is calls cls.__new__ then cls.__init__, e.g.: class RDFObject(object): # This metaclass prevents __init__ from being automatically called # after __new__ class __metaclass__(type): def __call__(cls, *args, **kwargs): return cls.__new__(cls, *args, **kwargs) # ... HTH -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list