Is a Borg rebellion possible? (a metaclass question)

Steven Bethard steven.bethard at gmail.com
Fri Sep 7 16:54:15 EDT 2007


Carsten Haese wrote:
> Indeed, if you have an __init__ method that shouldn't see the "group"
> argument, you need a metaclass after all so you can yank the "group"
> argument between __new__ and __init__. The following code seems to work,
> but it's making my brain hurt:
> 
> class SplinterBorgMeta(type):
>     def __call__(cls, *args, **kwargs):
>         inst = cls.__new__(cls, *args, **kwargs)
>         kwargs.pop("group",None)
>         inst.__init__(*args,**kwargs)
>         return inst
> 
> class SplinterBorg(object):
>     __metaclass__ = SplinterBorgMeta
>     _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
> 

I think I would probably write that as::

     >>> class SplinterBorgMeta(type):
     ...     def __init__(cls, name, bases, bodydict):
     ...         cls._shared_states = {}
     ...     def __call__(cls, *args, **kwargs):
     ...         group = kwargs.pop('group', None)
     ...         inst = cls.__new__(cls, *args, **kwargs)
     ...         inst.__dict__ = cls._shared_states.setdefault(group, {})
     ...         inst.__init__(*args, **kwargs)
     ...         return inst
     ...
     >>> class MyClass(object):
     ...     __metaclass__ = SplinterBorgMeta
     ...     def __init__(self, name):
     ...         self.name = name
     ...
     >>> a = MyClass('a')
     >>> aa = MyClass('aa')
     >>> b = MyClass('b', group='b')
     >>> bb = MyClass('bb', group='b')
     >>> a.name, aa.name, b.name, bb.name
     ('aa', 'aa', 'bb', 'bb')

That is, I don't think there's really a need for __new__ if you're using 
a metaclass. Just set the instance's __dict__ in the __call__ method of 
the metaclass.

STeVe



More information about the Python-list mailing list