Meta-class fun with PEP 318 [was Re: PEP 318 - posting draft]

Sean Ross sross at connectmail.carleton.ca
Sat Mar 27 13:23:57 EST 2004


For some reason I got caught up in using both decorate() and annotate(), but
you really only need one:

import sys

def delayed_decorate(method, *decorators, **attributes):
    "Decorate method during class instantation"
    method.__dict__.update(attributes)
    for decorator in decorators:
        method = decorator(method)
    return method

def decorate(funcname, *decorators, **attributes):
    "Mark method for delayed decoration"
    clsdict = sys._getframe(1).f_locals
    clsdict.setdefault("decorated", {})[funcname] = (decorators, attributes)


class MetaDecorate(type):
    "Enables delayed decoration and annotation of methods"
    def __new__(klass, name, bases, _dict):
        if "decorated" in _dict:
            for method, (decorators, attributes) in
_dict["decorated"].iteritems():
                _dict[method] = delayed_decorate(_dict[method], *decorators,
**attributes)
            del _dict["decorated"]
        return type.__new__(klass, name, bases, _dict)

class Decorated(object):
    __metaclass__ = MetaDecorate

class C(Decorated):
    a = "A"

    decorate("f", classmethod, author="Sean Ross", version="0.9.2")
    def f(klass):
        return klass.a

    decorate("g", staticmethod)
    def g():
        return "G"

print "C.f.author =", C.f.author
print "C.f.version =", C.f.version
print "C.f() =>", C.f()
print "C.g() =>", C.g()





More information about the Python-list mailing list