How to use "__new__"?
Heiko Wundram
modelnine at ceosg.de
Tue Mar 29 22:04:47 EST 2005
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20050330/eb08d43a/attachment.sig>
More information about the Python-list
mailing list