Is a Borg rebellion possible? (a metaclass question)

André andre.roberge at gmail.com
Fri Sep 7 11:54:38 EDT 2007


On Sep 7, 10:27 am, Carsten Haese <cars... at uniqsys.com> wrote:
> On Fri, 2007-09-07 at 12:31 +0000, André wrote:
> > In my application, I make use of the Borg idiom, invented by Alex
> > Martelli.
>
> > class Borg(object):
> >     '''Borg Idiom, from the Python Cookbook, 2nd Edition, p:273
>
> >     Derive a class form this; all instances of that class will share
> > the
> >     same state, provided that they don't override __new__; otherwise,
> >     remember to use Borg.__new__ within the overriden class.
> >     '''
> >     _shared_state = {}
> >     def __new__(cls, *a, **k):
> >         obj = object.__new__(cls, *a, **k)
> >         obj.__dict__ = cls._shared_state
> >         return obj
>
> > ----
> > This has worked very well so far, but is starting to impose some
> > unwanted constraints on my program design.
>
> > What I would like to do is, to put it figuratively, create a Borg
> > rebellion with various splinter groups.  In concrete Python terms, I
> > would like to have
>
> > class MyClass(Borg, ...):
> >    ...
>
> > seven_of_nine = MyClass(...)  # part of group "BORG"
> > two_of_nine = MyClass(...)
>
> > splinter1 = MyClass(..., group='splinter')
> > splinter2 = MyClass(..., group='splinter')
>
> > and have splinter 1 and splinter2 share the same state, but a
> > different state than the one shared by members of the BORG collective.
>
> > Any suggestions from the metaclass experts?
>
> You don't need a metaclass. Just turn _shared_state into a dictionary of
> shared states, keyed by the group name:
>
> class SplinterBorg(object):
>     _shared_states = {}
>     def __new__(cls, *a, **k):
>         group = k.pop("group","BORG")
>         obj = object.__new__(cls, *a, **k)
>         obj.__dict__ = cls._shared_states.setdefault(group,{})
>         return obj
>
> HTH,
>
> --
> Carsten Haesehttp://informixdb.sourceforge.net

Unfortunately, it fails.  Here's what I tried, followed by the
traceback
class SplinterBorg(object):
    _shared_states = {}
    def __new__(cls, *a, **k):
        group = k.pop("group","BORG")
        obj = object.__new__(cls, *a, **k)
        obj.__dict__ = cls._shared_states.setdefault(group,{})
        return obj

class MyClass(SplinterBorg):
   def __init__(self, name):
       self.name = name

a1 = MyClass('a')
a2 = MyClass('aa')
b1 = MyClass('b', group="B")


Traceback (most recent call last):
  File "test.py", line 15, in <module>
    b1 = MyClass('b', group="B")
TypeError: __init__() got an unexpected keyword argument 'group'





More information about the Python-list mailing list