singleton or Borg?

Andy Jewell andy at wild-flower.co.uk
Mon Sep 15 17:00:28 EDT 2003


On Sunday 14 Sep 2003 11:00 pm, Rajarshi Guha wrote:
> Hi, I'm having a little problem with understanding the working of a
> singleton and borg class. Basically I nedd an class whose state will be
> shared across several modules. I found the stuff on the ASPN cookbook but
> it does'nt seem to be working for me. I've included some code:
>
> Borg.py:
> --------
> class Borg:
>     __shared_state = {}
>     def __init__(self):
>         self.__dict__ = self.__shared_state
>         self.val = {}
>
> class Singleton(object):
>     def __new__(type):
>         if not '_the_instance' in type.__dict__:
>             type._the_instance = object.__new__(type)
>         return type._the_instance
>
> class Tester(Singleton):
>     def __init__(self):
>         self.val = {}
>
> t.py:
> -----
> import Borg,v
>
> x = Borg.Tester()
> x.val['a'] = 1
>
> print x.val
> v.func()
> print x.val
>
> v.py:
> -----
> import Borg
>
> def func():
>     y = Borg.Tester()
>     print y.val, '...from t.py'
>     y.val['a'] = 2
>     return
>
> I had expected to see:
> {'a':1}
> {'a':1} ...from t.py
> {'a':2}
>
> However I get
> {'a':1}
> {} ...from t.py
> {'a':2}
>
>
> Should'nt the instantiation of val in v.func() just use the val that was
> already created when it was instatntiated in t.py?
>
> I just cant seem to wrap my head around this oen, so any suggestions
> would be appreciated.
>
> Thanks

Rajarshi,

You define but never reference class Borg.Borg.  Borg.Tester imported by t.py 
and v.py is descended from class 'Borg.Singleton', which is in turn descended 
from built-in class 'object', i.e. this lineage is of 'new style classes'.  
Class 'Borg.Borg' is an old-style class; and inherits from nothing.  

Since 'Borg.Borg' is never referenced, nor any instances of it created, your 
'shared class variable' '__shared_state = {}'  never gets used.

Here's my take on this:
>>> class Borg(object):
	__shared={}
	def __init__(self):
		self.__dict__=self.__shared

----8<----		
>>> v=Borg()
>>> v.__shared={"a":1}
>>> v.__shared
{'a': 1}
>>> w=Borg()
>>> w.__shared
{'a': 1}
>>> w.__shared["b"]=2
>>> v.__shared
{'a': 1, 'b': 2}
>>> v.__shared is w.__shared
True


>>> class Singleton(object):
	def __new__(self):
		if not self.__dict__.has_key("instance"):
			self.instance=object.__new__(self)
		return self.instance

	
>>> x=Singleton()
>>> x
<__main__.Singleton object at 0x40953d6c>
>>> y=Singleton()
>>> y
<__main__.Singleton object at 0x40953d6c>
>>> x is y
True
>>> x.test=1
>>> y.test
1

----8<----		

This clearly shows that an object of Borg class has a shared /class/ variable, 
Borg.__shared: I made an instance of Borg, v, and assigned to its __shared 
dict.  I then made a second instance of Borg, w.  Displaying its __shared 
dict reveals that it has the same contents as I assigned to v.__shared.  I 
assign a new key:value pair and then display the original object's .__shared 
dict: lo and behold, v.__shared has the same keys!  Final proof is provided 
by checking if 'v.__shared is w.__shared' - of course it is.

Then I define Singleton (based on your example).  The singleton class's 
__new__ method prevents any more than one instance ever being created.  (I 
didn't use the word /type/ as this is a builtin function).  I created two 
'instances' of Singleton, but as we can see, they're both the same object.

HTH

-andyj






More information about the Python-list mailing list