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