Shrinidhi Kanchi
Shrinidhi Kanchi

Reputation: 136

Getting parameter name

I searched about it and got the following, python obtain variable name of argument in a function but i am not getting required answer and am actually getting an error saying add () takes exactly 0 arguments when i used kwargs. So reposted to get an answer if there is any.

i have the following code,

def add ( arg1, arg2):  
     z = arg1 + arg2
     print arg1Name, arg2Name, z

x = 10
y = 5  
add( x,y )

i want output as

x y 15

Upvotes: 8

Views: 600

Answers (4)

GLHF
GLHF

Reputation: 4044

One liner solution here,**kwargs returns a dict, check that with;

def add(**kwargs):
    print (kwargs)

add(x=5,y=10)

>>> 
{'y': 10, 'x': 5}
>>> 

It's a normal dict. You can reach the each element with basic dict methods.

print (kwargs.keys())

>>> 
dict_keys(['y', 'x'])
>>> 

Using kwargs is a tradition actually, you can use whatever you want instead of it. Here is the solution,print dict keys and sum of values;

def add(**ChuckNorris): #instead of **kwargs
    print (" ".join(ChuckNorris.keys()),sum(list(ChuckNorris.values())))

add(x=5,y=10)

>>> 
x y 15
>>> 

Upvotes: 2

Eugene Soldatov
Eugene Soldatov

Reputation: 10145

You should use func_code.co_varnames attribute of your function to access parameters names:

def add(arg1, arg2):
    z = arg1 + arg2
    print ' '.join(add.func_code.co_varnames[:2]) + ' ' + str(z)

add(10, 5)

Output:

arg1 arg2 15

You can read more about internal attributes here: https://docs.python.org/2/library/inspect.html#types-and-members

Upvotes: 7

Marcin
Marcin

Reputation: 238957

I think the closest you can get to what you want is as follows:

def add (**kwargs):    

    assert len(kwargs) == 2, "Not enough arguments"    

    keys = kwargs.keys()
    z = kwargs[keys[0]] +  kwargs[keys[1]]
    print keys[0], keys[1], z


x = 10
y = 5  
add(x=x,y=y)
add(w=11,t=11)

Results in:

y x 15
t w 22

Upvotes: 4

Tris Forster
Tris Forster

Reputation: 162

You can do it using the traceback module.

def get_current_arg_names():
  import traceback, re
  tb = traceback.extract_stack()
  method = tb[-2][2]
  func_call = tb[-3][3]
  args = re.search('%s\s*\((.*?)\)' % method, func_call).group(1)
  return [ x.strip() for x in args.split(',') ]

def add(arg1, arg2):
  z = arg1 + arg2
  print get_current_arg_names(), z
  return z

x = 1
y = 3
print add(x, y)

However the regex would need to be improved and event then, there is a requirement that the function call not be spread across multiple lines.

Better to modify you code if possible as this is messy.

Upvotes: 1

Related Questions