Using metaclasses to play with decorators.
Jeff Epler
jepler at unpythonic.net
Mon Jun 14 21:10:11 EDT 2004
Here's another way to use metaclasses to specify decorators:
class O(object):
__metaclass__ = DecoratedMeta
def f(cls, x, __decorate__ = [classmethod]):
return x*x
def g(x, __decorate__ = [staticmethod]):
return x**3
def h(self, x):
return x
I think this is a terrible abuse, and I would never want to see this
used in real-world code, but that didn't stop me from writing the code
to show how *cough*clever*cough* I am.
Here's the little-tested implementation:
import inspect, types
def decorate(func):
argnames, _, _, defaults = inspect.getargspec(func)
try:
i = argnames.index("__decorate__")
except ValueError: # x not in list
return func
j = i - len(argnames)
decorators = defaults[j]
decorators.reverse()
# XXX: Add code here to remove __decorate__ from func's arglist
for d in decorators:
func = d(func)
return func
def DecoratedMeta(name, bases, ns):
for k, v in ns.iteritems():
if not isinstance(v, types.FunctionType):
continue
ns[k] = decorate(v)
return type(name, bases, ns)
if __name__ == '__main__':
class O(object):
__metaclass__ = DecoratedMeta
def f(cls, x, __decorate__ = [classmethod]):
return x*x
def g(x, __decorate__ = [staticmethod]):
return x**3
def h(self, x):
return x
print O.f(3), O.g(4)
o = O()
print o.f(5), o.g(6), o.h(7)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20040614/08b21c77/attachment.sig>
More information about the Python-list
mailing list