python - Decorator to allow function to accept arbitrary arguments -
how can write decorator decorated functions can accept (and ignore) arbitrary arguments?
i have functions this:
def foo(x): return x def foo2(x, y): if bar(y): return x else: return x + 1 def foo3(x, y, z): ... foo() can calculate return value given x based on x, foo2() needs parameter, , foo3() needs third parameter. have method elsewhere that, among other things, calls either foo(), foo2(), etc depending on user-specified argument.
right now, method grabs appropriate function getattr(user_arg) , calls of x, y, z. avoid typeerror wrong number of arguments, foo functions defined *args this:
def foo(x, *args): return x but i'd have decorator avoid including *args in every single foo function definition. there way that? or can suggest better way organize code?
one way write method this:
if user_arg == 'foo': foo(x) elif user_arg == 'foo2': foo2(x, y) elif user_arg == 'foo3': foo3(x, y, z) but i'd avoid this, because there lot of foo functions, , because i'd make possible add new foo functions without having add branch method.
edit: clarify, it's not case need call different foo function based on number of arguments. it's arbitrary (user-specified) of foo functions called.
def foo3(x, y, z): return x + y + z def foo4(x, y, z): return x + y - z
you can use inspect.getargspec determine arguments decorated function takes:
import functools import inspect def ignore_extra_arguments(func): args, varargs, kwvarargs, defaults = inspect.getargspec(func) @functools.wraps(func) def wrapper_func(*wrapper_args, **wrapper_kwargs): if varargs none: # remove positional arguments wrapper_args = wrapper_args[:len(args)] if kwvarargs none: # remove keyword arguments wrapper_kwargs = {k: v k, v in wrapper_kwargs.iteritems() if k in args} return func(*wrapper_args, **wrapper_kwargs) return wrapper_func this can optimized little lifting if checks out of wrapper_func, @ expense of writing more code.
Comments
Post a Comment