Borg - is that a singleton?

Alex Martelli aleax at aleax.it
Sat Mar 1 02:14:59 EST 2003


Graham Fawcett wrote:
   ...
> Remember that Borg is a *design pattern*. I don't think it was ever
> intended for use as a base class of your class hierarchy.

No problem using it as a base class -- as long as you use it
_advisedly_.  http://www.aleax.it/Python/5ep.html has more
info about that, and shows the following snippet:

class Borg:
    _shared_state = {}
    def __init__(self):
        self.__dict__ = self._shared_state

note only ONE leading underscore to the shared state dict --
that's key.  Immediately afterwards, the text explains:

"""
Your class may in turn override Borg's _shared_state class attribute. 
It is exactly in order to allow this "data override" that 
Borg.__init__ accesses the attribute through self, not directly by
qualifying Borg, and the attribute's name has one leading underscore, 
not two. This data-member overriding, or lack thereof, determines 
whether your class also shares state with other subclasses of Borg: 
you can easily arrange this in different ways, but, of course, 
resistance is futile, so don't even bother trying to arrange that.
"""

In other words:


> You would "borgify" your classes *individually* :

Sure, if that's what you wish.

> class Foo:
>     __shared_state = {}
>     def __init__(self):
>         self.__dict__ = self.__shared_state

Too much work!  Just:

class Foo(Borg): _shared_state = {}

> class Bar:
>     __shared_state = {}
>     def __init__(self):
>         self.__dict__ = self.__shared_state

Ditto: just

class Bar(Borg): _shared_state = {}


> In other words, imitate the Borg class, don't subclass it. There are,
> after all, only two relevant lines of code to add -- an easy task.

But with subclassing AND data override, it's even easier.  The
power of Python often avoids the need for much "copy and paste
coding", in favour of reuse -- and this can be such a case.


Alex





More information about the Python-list mailing list