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