decorating functions with generic signatures (not for the faint of heart)
Michele Simionato
michele.simionato at gmail.com
Fri Apr 8 06:54:39 EDT 2005
I said it was very little tested! ;)
This should work better:
#<decorate.py>
def _signature_gen(varnames, n_default_args, n_args,
rm_defaults=False):
n_non_default_args = n_args - n_default_args
non_default_names = varnames[:n_non_default_args]
default_names = varnames[n_non_default_args:n_args]
other_names = varnames[n_args:]
n_other_names = len(other_names)
for name in non_default_names:
yield "%s" % name
for i, name in enumerate(default_names):
if rm_defaults:
yield name
else:
yield "%s = arg[%s]" % (name, i)
if n_other_names == 1:
yield "*%s" % other_names[0]
elif n_other_names == 2:
yield "*%s" % other_names[0]
yield "**%s" % other_names[1]
def decorate(func, caller):
argdefs = func.func_defaults or ()
argcount = func.func_code.co_argcount
varnames = func.func_code.co_varnames
signature = ", ".join(_signature_gen(varnames, len(argdefs),
argcount))
variables = ", ".join(_signature_gen(varnames, len(argdefs),
argcount,
rm_defaults=True))
lambda_src = "lambda %s: call(func, %s)" % (signature, variables)
dec_func = eval(lambda_src, dict(func=func, call=caller,
arg=argdefs))
dec_func.__name__ = func.__name__
dec_func.__doc__ = func.__doc__
dec_func.__dict__ = func.__dict__.copy()
return dec_func
#</decorate.py>
More information about the Python-list
mailing list