410

Is there an easy way to be inside a python function and get a list of the parameter names?

For example:

def func(a,b,c):
    print magic_that_does_what_I_want()

>>> func()
['a','b','c']

Thanks

0

4 Answers 4

501

Well we don't actually need inspect here.

>>> func = lambda x, y: (x, y)
>>> 
>>> func.__code__.co_argcount
2
>>> func.__code__.co_varnames
('x', 'y')
>>>
>>> def func2(x,y=3):
...  print(func2.__code__.co_varnames)
...  pass # Other things
... 
>>> func2(3,3)
('x', 'y')
>>> 
>>> func2.__defaults__
(3,)
Sign up to request clarification or add additional context in comments.

11 Comments

that'd be func.func_code.co_varnames[:func.func_code.co_argcount] since co_varnames is a tuple of all variables present in the function
In python3 this would be func.__code__.co_varnames
This only works for non 'builtin_function_or_method'.
I use Python 2.7.8, and __code__ seems to be backported. func_code also still works.
Please use inspect. Otherwise, your code doesn't work well with functools.wraps in 3.4+. See stackoverflow.com/questions/147816/…
|
309

locals() returns a dictionary with local names:

def func(a, b, c):
    print(locals().keys())

prints the list of parameters. If you use other local variables those will be included in this list. But you could make a copy at the beginning of your function.

8 Comments

print locals().keys() will return ['arg']. I used print locals.get('arg')
Thank you! I have a new love for "found {thing} in {place}, took {action}, resulting in {result}".format(**locals()) instead of "found {thing} in {place}, took {action}, resulting in {result}".format(thing=thing, place=place, action=action, result=result)
watch out, locals() returns namespace vars too, eg def func(a,b,c): d=4; print(locals()['d'])
@BrunoBronosky why not just use f-strings? f'found {thing} in {place}, took {action}, resulting in {result}'
@speedstyle f-strings were introduced in Python 3.6. The comment was from 3.5. (And yes, f-strings are waay better :D )
|
200

If you also want the values you can use the inspect module

import inspect

def func(a, b, c):
    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)
    print 'function name "%s"' % inspect.getframeinfo(frame)[2]
    for i in args:
        print "    %s = %s" % (i, values[i])
    return [(i, values[i]) for i in args]

>>> func(1, 2, 3)
function name "func"
    a = 1
    b = 2
    c = 3
[('a', 1), ('b', 2), ('c', 3)]

4 Comments

Kelly Yancey's blog has a great post explaining this in detail and giving a slightly more refined version, plos a comparison with, e.g. unbeknown's solution. Recommended.
what about def foo(first, second, third, *therest):?
how to use this functionality in a decorator?
@JDOaktown a decorator function/class takes a function/class as its argument. Therefore, given a python 3 decorator function def decorate(fn): ..., you would simply do fn_params = inspect.signature(fn).parameters in the decorator and use logic to get the argument values in fn's wrapper, def wrapper(*args, **kwargs): ..., which is returned by the decorator.
157
import inspect

def func(a,b,c=5):
    pass

>>> inspect.getargspec(func)  # inspect.signature(func) in Python 3
(['a', 'b', 'c'], None, None, (5,))

so for getting arguments list alone use:

>>> inspect.getargspec(func)[0]
['a', 'b', 'c']

8 Comments

That's not inside the function..
you can do it inside the function too
this is actually better, since it shows how to get at parameters of method you didn't write yourself.
@UnverifiedContact Just do it inside the function :-). You can access the function name with no problem (ie recursion) so inspect.getargspec(func) from within func should work just fine
@DavidC Updated link inspect.signature
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.