Am Mittwoch, 30. März 2005 04:36 schrieb Heiko Wundram: > You could extend the above example quite easily to deal with deallocation > (a reference to each created singleton is retained using the above class, > always, as long as the program is running) and also to make it threadsafe > or to disable initialization in case the singleton has already been > initialized before.
Just to post a complete example of a Singleton class which works in a multithreaded environment, and allows you to update future instances (a sample, untested implementation): <code> import threading import weakref class SingletonBase(object): __buffer = {} __bufferLock = threading.RLock() def __new__(cls,*args,**kwargs): cls.__bufferLock.acquire() try: inst = cls.__create_new__(buffer,*args,**kwargs) if not hasattr(inst,"_SingletonBase__instanceLock"): inst.__instanceLock = threading.RLock() inst.__initialized = False return inst finally: cls.__bufferLock.release() @classmethod def __create_new__(cls,*args,**kwargs): return super(SingletonBase,cls).__new__(cls) def __init__(self,*args,**kwargs): self.__instanceLock.acquire() try: if not self.__initialized: self.__initialize_new__(*args,**kwargs) self.__initialized = True else: self.__update_old__(*args,**kwargs) finally: self.__instanceLock.release() def __initialize_new__(self,*args,**kwargs): pass def __update_old__(self,*args,**kwargs): pass class Singleton(SingletonBase): @classmethod def __create_new__(cls,buffer,somearg): inst = buffer.get(somearg,lambda: None)() if inst is None: inst = super(Singleton,cls).__create_new__(cls) buffer[somearg] = weakref.ref(inst) return inst def __initialize_new__(self,somearg): print "Initializing new instance." self.__somearg = somearg def __update_old__(self,somearg): print "Updating old." assert somearg == self.__somearg # Initialize three singletons. print "Creating singletons for 1, 2, 1." x = Singleton(1) y = Singleton(2) z = Singleton(1) # Print them out. print "\nThree singletons: x, y, z." print repr(x) print repr(y) print repr(z) # Assert that x is not y, and x is z. print "\nx is y, x is z" print x is y print x is z # Delete names, and make sure weakrefs are unbound. print "\nRemove all three singletons." del x del y del z # Recreate singleton for value 1. print "\nRecreating singleton for value 1." x = Singleton(1) y = Singleton(1) # Print them out. print "\nNew Singleton(1): x, y." print repr(x) print repr(y) # Check that x is y. print "\nx is y" print x is y </code> The above program prints the following output when run: <output> Creating singletons for 1, 2, 1. Initializing new instance. Initializing new instance. Updating old. Three singletons: x, y, z. <__main__.Singleton object at 0xb7bfbc6c> <__main__.Singleton object at 0xb7bfbcac> <__main__.Singleton object at 0xb7bfbc6c> x is y, x is z False True Remove all three singletons. Recreating singleton for value 1. Initializing new instance. Updating old. New Singleton(1): x, y. <__main__.Singleton object at 0xb7bfbc6c> <__main__.Singleton object at 0xb7bfbc6c> x is y True </output> HTH! -- --- Heiko.
pgpQKQoZkoCMz.pgp
Description: PGP signature
-- http://mail.python.org/mailman/listinfo/python-list