Tsuu
Tsuu

Reputation: 116

How to get the parameter name of an argument passing into a function in Python?

I'm making a decorator that prints out the input and output values of a function when it is called. I wonder how I can get the parameter name of an argument passing into the function. In the sample function below, I expect that the first argument - 5, will be of the parameter 'multiplier' and the rest will be of '*numbers', but how can I transfer those information into the decorator, because the f function in the decorator only have **args and **kwargs as parameter, not the actual parameter name of the function? Hope you guys can help me, thanks a lot.

Here is the decorator:

def log(with_input=True):
    def inner(f):
        def wrapper(*args, **kwargs):
            rv = f(*args, **kwargs)
            print('*' * 40)
            print("function: ", f.__name__,inspect.signature(f))
            if with_input:
                print("input: ")
                for arg in args:
                    print('  param_name',arg)
            print("output:", rv)
            return rv
        return wrapper
    return inner

This is the sample code to test the decorator:

@log(with_input=True)
def multiplier_sum(multiplier,*numbers):
   sum = 0
   for n in numbers:
       sum += n
   return sum * multiplier

multiplier_sum(5,2,3,4) 

This is the output, where the parameter name associated with the argument is what I'm expected to in place of param_name:

****************************************
function:  multiplier_sum (multiplier, *numbers)
input: 
  param_name 5
  param_name 2
  param_name 3
  param_name 4
output: 45

Upvotes: 1

Views: 272

Answers (2)

Roy2012
Roy2012

Reputation: 12523

Cool question. Here's a solution:

import inspect

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("signature: ", inspect.signature(func))
        bound_sig = inspect.signature(func).bind(*args, **kwargs)
        print("bound signature: ", bound_sig)
        print("arguments: ", bound_sig.arguments)
        func(*args, **kwargs)
    return wrapper

@my_decorator
def f(x):
    print (f"we're in foo now, and x is {x}")

f(5)

results in:

signature:  (x)
bound signature:  <BoundArguments (x=5)>
arguments:  OrderedDict([('x', 5)])
we' re in foo now, and x is 5

Upvotes: 1

vks
vks

Reputation: 67988

function.__code__.co_varnames

This will give the parameter names.

function.__code__.co_argcount

This will give the argument count.

or

from inspect import getargspec
print getargspec(function)

Upvotes: 0

Related Questions