[Python-3000] mixin class decorator (original) (raw)

tomer filiba tomerfiliba at gmail.com
Thu May 10 13:36:55 CEST 2007


with the new class decorators of py3k, new use cases emerge. for example, now it is easy to have real mixin classes or even mixin modules, a la ruby.

unlike inheritance, this mixin mechanism simply merges the namespace of the class or module into the namespace of the decorated class. it does not affect class hierarchies/MRO, and provides finer granularity as to what methods are merged, i.e., you explicit mark which methods should be merged.

def mixinmethod(func): """marks a method as a mixin method""" func.is_mixin = True return func

def get_unbound(obj, name): if name in obj.dict: return obj.dict[name] else: for b in obj.mro(): if name in b.dict: return b.dict[name]

def mixin(obj, override = False): """a class decorator that merges the attributes of 'obj' into the class""" def wrapper(cls): for name in dir(obj): attr = get_unbound(obj, name) if getattr(attr, "is_mixin", False): if override or not hasattr(cls, name): setattr(cls, name, attr) return cls return wrapper

Example

class DictMixin: @mixinmethod def iter(self): for k in self.keys(): yield k

@mixinmethod
def has_key(self, key):
    try:
        value = self[key]
    except KeyError:
        return False
    return True

@mixinmethod
def clear(self):
    for key in self.keys():
        del self[key]
...

@mixin(DictMixin) class MyDict: def keys(self): return range(10)

md = MyDict() for k in md: print k

does it seem useful? should it be included in some stdlib? or at least mentioned as a use case for class decorators in PEP 3129? (not intended for 3.0a1)

-tomer



More information about the Python-3000 mailing list