[Python-3000] mixin class decorator

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