Reputation: 1158
I have a decorator, and in that decorator I want to check if the decorated function has an argument with the name query
. If it exists I want to detect its position in *args
like this: args[1]
. I want to perform this in wrapper function. I want to do something like this:
def some_decorator(func):
@wraps(func)
def wrapper_func(*args, **kwargs):
ind = 0
query = ''
for arg in args:
if arg.__name__ == 'query'
query = 'Found'
break
ind +=1
if query == 'Found':
query = args[ind]
return wrapper_func
For clarity, I use it like this:
@some_decorator
def find_all(self, some_arg, query=None):
pass
The thing is, I use the decorator also for other functions, with different signatures that may or may not have query
argument. I hope this clarifies things.
Upvotes: 0
Views: 360
Reputation: 24691
If I'm understanding you correctly, then I think you can use the inspect
module:
import inspect
...
def some_decorator(func):
def wrapper_func(*args, **kwargs):
# get function signature using inspect.signature()
signature = inspect.signature(func)
# find the subset of arguments that are positional-only
positional_args = [name for name in signature.parameters
if signature.parameters[name].kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD)]
# This should give us the names of args that *may* be positional.
# They should also be in the proper order, since positional-or-keyword args
# cannot precede positional-only args.
# Now, we can search for a positional arg named 'query', get an index...
try:
query_idx = positional_args.index('query')
except ValueError:
query_idx = -1
# ... and extract the corresponding value passed for that in *args
if 0 <= query_idx < len(args):
query = args[query_idx]
else:
query = None
# then do something with that
...
return wrapper_func
Upvotes: 2
Reputation: 75
You could try with array.index()
query = ''
try:
idx = args.index('query')
except ValueError:
idx = -1
if idx != -1:
query = args[idx]
Upvotes: -1