recursive decorator
Ethan Furman
ethan at stoneleaf.us
Tue Sep 8 19:01:49 EDT 2009
Michele Simionato wrote:
[snip]
> Yes, it is portable. BTW, here is what you want to do (requires
> decorator-3.1.2):
>
> from decorator import FunctionMaker
>
> def bindfunc(f):
> name = f.__name__
> signature = ', '.join(FunctionMaker(f).args[1:]) # skip first arg
> return FunctionMaker.create(
> '%s(%s)' % (name, signature),
> 'return _func_(%s, %s)' % (name, signature),
> dict(_func_=f), defaults=f.func_defaults,
> doc=f.__doc__, module=f.__module__)
I figured there must be an easy way using your module. Here is what I
came up with *not* using the module -- this whole thing was definitely a
mind-stretching exercise. Many thanks for your decorator routines -- no
way could I have gotten this far without them to guide me!
def bind_func(func):
name = func.__name__
argspec = inspect.getargspec(func)
self = argspec[0][0]
newargspec = (argspec[0][1:], ) + argspec[1:]
signature = inspect.formatargspec( \
formatvalue=lambda val: "", *newargspec)[1:-1]
new_func = 'def _wrapper_(%(signature)s):\n' \
' return %(self)s(_wrapper_, %(signature)s)' % \
{'signature':signature, 'self':'old_func'}
evaldict = {'old_func':func}
exec new_func in evaldict
wrapped = evaldict['_wrapper_']
wrapped.__name__ = name
wrapped.__doc__ = func.__doc__
wrapped.__module__ = func.__module__
wrapped.__dict__ = func.__dict__
wrapped.func_defaults = func.func_defaults
return wrapped
~Ethan~
More information about the Python-list
mailing list