Singleton-like pattern

Michele Simionato mis6 at pitt.edu
Sat Aug 2 11:53:46 EDT 2003


pedro.werneck at bol.com.br (Pedro Werneck) wrote in message news:<ef72fb2b.0308011825.63599ff2 at posting.google.com>...
> On 1 Aug 2003, Bengt Richter wrote:
> 
> > >> class MultiSingleton(type):
>  class MultiSingleton(object):
> > >>     def __call__(cls, *args, **kwds):
>      def __new__(cls, *args, **kwds):
> > >>         cache = cls.__dict__.get('__cache__')
> > >>         if cache is None:
> > >>             cls.__cache__ = cache = {}
> > >>         tag = str(args) + str(kwds)
>          tag = '%r%r'% (args, kwds)   # might be an alternative
> > >>         if tag in cache:
> > >>             return cache[tag]
> > >>         obj = object.__new__(cls)
> > >>         obj.__init__(*args, **kwds)
> > >>         cache[tag] = obj
> > >>         return obj
> 
> This is exactly what I did at first... I only changed it to a metaclass
> because I was adding it to a module that already contain some other
> metaclasses I use; I think it's more elegant as I said before... a
> 'quick and dirty' benchmark with the timeit module returned the
> folowing results, and in this project I will be dealing with a database
> of 7000+ items, this 20% bit may help a little:
> 
> __metaclass__:
> [39.744094967842102, 40.455733060836792, 42.027853965759277]
> 
> __new__:
> [47.914013981819153, 48.721022009849548, 49.430392026901245]
> 
> 
> On 1 Aug 2003, Michele Simionato wrote:
> 
> > "memoize" is a possible name for this. Notice that the metaclass is a
> > bit of overkill, you may well use a simple function for this job.
> 
> Hey... you wrote such a good article on python metaclasses and now don't
> want people to use them ? :)

Maybe it is because I know them that I don't want to abuse them ;)
Consider also that not everybody knows about metaclasses, and 
I want my code to be readable to others; finally, there is
Occam's rasor argument (i.e. do not use metaclasses without necessity).

> > Does (args,kw) work in general? IWT you could easily get something unhashable?
> > IWT using a tuple of actual args may also be a bad idea since it would prevent callers'
> > temp args from being garbage collected. I use repr to avoid that, maybe mistakenly?
>  
> > About the issue of finding a suitable key, in the same situation I have
> > used the tuple (args,kw) as key. But me too I would like to ask if this is a
> > good idea. What's the custom solution for getting a good key from
> > a dictionary ?
> 
> Actually, (args, kw) doesn't work at all, even if you only get hashable
> arguments... the 'kw' dict invalidate it as a key... besides, there's the
> garbage collection problem, as Bengt Richter mentioned...

Yes, as I replied to Carl Banks, actually I have got problems with
(args,kw) and I think at the end I used args+tuple(kw.iteritems()),
but I had forgotten at the time of the posting.
 
> The "%r%r"%(args, kwds) works, as well as str((args, kwds))), but it
> breaks if you get as argument an object with the default __repr__, as
> the object id may be different, even if they are equal. Overriding __repr__
> and returning a real representation avoids this problem.
> 
> Thanks for your time.
> 
> Pedro Werneck


Michele




More information about the Python-list mailing list