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 -- http://mail.python.org/mailman/listinfo/python-list