J Peyret wrote: > >>> class RDFObject(object): > > ... cache ={} > ... isInitialized = False > ... def __new__(cls,uri,*args,**kwds): > ... try: > ... return cls.cache[uri] > ... except KeyError: > ... print "cache miss" > ... res = cls.cache[uri] = object.__new__(cls) > ... return res > ... def __init__(self,uri): > ... if self.isInitialized: > ... return > ... print "__init__ for uri:%s" % (uri) > ... self.isInitialized = True > ...>>> r1 = RDFObject(1)
Thanks. I first got that option, but discarded it because of the following (sloppy) coding, which still leads to double initializations: class MySubclass(RDFObject): def __init__(self, uri): self.somevar = [] RDFObject.__init__(self, uri) # .... In this case, somevar is re-initialized before the return statement in the parent. I'll use __metaclass__ solution. Here is my (non-threaded) version: class RDFObject(object): _cache = {} # class variable is shared among all RDFObject instances class __metaclass__(type): def __call__(cls, *args, **kwargs): return cls.__new__(cls, *args, **kwargs) def __new__(cls, uri, *args, **kargs): if uri not in cls._cache: obj = object.__new__(cls) cls._cache[uri] = obj obj.__init__(uri, *args, **kargs) return cls._cache[uri] def __init__(self, uri): self.uri = uri print self.__class__, uri # ... Thanks for the other 'things to keep in mind'. I found those all very informative! Two more things for all lurkers out there: - If you override __call__ in __metaclass__ to only call __new__, but skip on __init__, you must make sure to call __init__ elsewhere. For example, from __new__: if uri not in cls._cache: obj = object.__new__(cls) cls._cache[uri] = obj obj.__init__(uri, *args, **kargs) - My "thread safe" code was in fact NOT thread safe. It still can create the same object twice in the (very unlikely event) that thread #2 executes "cls._cache[uri] = obj" just between the lines "if uri not in cls._cache:" and "threadlock.acquire()" in thread #1. (bonus points for those who caught this one). Perhaps indeed the try...except KeyError is even prettier (no idea about speed, but let's rename this thread if we want to discuss performance measurements). Thanks all! Freek -- http://mail.python.org/mailman/listinfo/python-list