Borg vs Singleton vs OddClass

Lie Lie.1296 at gmail.com
Sat Sep 27 20:12:00 CEST 2008


This is probably unrelated to Python, as this is more about design
pattern. I'm asking your comments about this design pattern that is
similar in functionality to Singleton and Borg: to share states.

I'm thinking about this design pattern (I don't know if anyone has
ever thought of this pattern before):

class OddClass(object):
    def __init__(self):
        global OddClass
        OddClass = self
    def __call__():
        return self

The OddClass is a class that would overwrite its own class definition
at its first instantiation. OddClass defines __call__ so that
subsequent "instantiation" (technically it is no more an
instantiation, but Duck Typing says it does) of the class would return
the single instance.

It do have a problem though, that you can't do isinstance(a, OddClass)
since the name OddClass no longer refers to the OddClass class
descriptor, but to an instance of OddClass. I don't think that's much
of a problem though since using isinstance() is generally not a good
idea in python (although OddClass do use global which many people,
including me, would usually consider as bad form).

The problem with Borg is that it is not inheritable (in certain
sense[1]) and only work with old-style class (which is due to be
completely removed on py3k)[2], Singleton and OddClass is inheritable.

>>> class Singleton(object): ...
>>> s = Singleton()
>>> class A(Singleton): pass
>>> class B(Singleton): pass
>>> a = A()
>>> b = B()
>>> s.foo, a.bar = "bar", 42
>>> b.foo, b.bar
... Traceback, Attribute Error ...

>>> class OddClass(object): ...
>>> s = OddClass()
>>> class A(OddClass): pass
>>> class B(OddClass): pass
>>> a = A()
>>> b = B()
>>> s.foo, a.bar = "bar", 42
>>> b.foo, b.bar
... Traceback, Attribute Error ...

but for Borg, see [1]

[1] classes that inherits from Borg shares state not only within
children, but also with their parents and cousins. That means
inheriting from Borg is useless, and that also means one Borg code for
every state sharing classes, instead of inheriting from Singleton/
OddClass. In code:
>>> class Borg: ...
>>> class A(Borg): ...
>>> class B(Borg): ...
>>> s, a, b = Borg(), A(), B()
>>> s.foo, a.attr = "bar", 42
>>> b.foo, b.attr
"bar" 42
>>> # we want b.foo and b.attr to raise error since .foo, and .bar isn't B's shared state, it's A's and Borg's shared state

[2] Actually in new-style class, they say Borg can use __slots__, but
they say it'd be slightly more complex



More information about the Python-list mailing list