Getting List of Parameter Names Inside Python Function

Getting list of parameter names inside python function

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,)

For Python 2.5 and older, use func_code instead of __code__, and func_defaults instead of __defaults__.

How to get method parameter names?

Take a look at the inspect module - this will do the inspection of the various code object properties for you.

>>> inspect.getfullargspec(a_method)
(['arg1', 'arg2'], None, None, None)

The other results are the name of the *args and **kwargs variables, and the defaults provided. ie.

>>> def foo(a, b, c=4, *arglist, **keywords): pass
>>> inspect.getfullargspec(foo)
(['a', 'b', 'c'], 'arglist', 'keywords', (4,))

Note that some callables may not be introspectable in certain implementations of Python. For Example, in CPython, some built-in functions defined in C provide no metadata about their arguments. As a result, you will get a ValueError if you use inspect.getfullargspec() on a built-in function.

Since Python 3.3, you can use inspect.signature() to see the call signature of a callable object:

>>> inspect.signature(foo)
<Signature (a, b, c=4, *arglist, **keywords)>

Python list function argument names

Use the inspect module from Python's standard library (the cleanest, most solid way to perform introspection).

Specifically, inspect.getargspec(f) returns the names and default values of f's arguments -- if you only want the names and don't care about special forms *a, **k,

import inspect

def magical_way(f):
return inspect.getargspec(f)[0]

completely meets your expressed requirements.

How to pass a list of function names as a parameter?

As suggestet in the comments, pass function objects in a list to your function and call them. This will not just work with numpy, but with all Python functions:

import numpy as np
func_list = [np.mean, np.std]

for func in func_list:
x = np.random.random(10)
print func(x)

Make sure the function calls work all the same way, i.e. x as first parameter.

The above is pretty similar to how function renaming works:

import time

another_sleep = time.sleep
another_sleep(1) # Sleep for one second

You create a function object (time.sleep) and assign it to a variable (another_sleep). Now you can call it with the variable's name (another_sleep(1)).

Get the names of a Python function’s parameters when it is inside a decorator

def _component_name_does_not_exist_error(func):
@functools.wraps(func)
def function_wrapper(self, *args, **kwargs):
if not self._does_component_exist(kwargs['component_name']):
return self._create_response(
False,
f"Component named {kwargs['component_name']} doesn't exist"
)
return func(self, *args, **kwargs)

return function_wrapper

This works for me
(Thank you @wstk for suggesting your answer and helping me reaching the answer)

Listing variables expected by a function in Python?

You can use either the inspect.signature() or inspect.getfullargspec() functions:

import inspect

argspec = inspect.getfullargspec(somefunction)
signature = inspect.signature(somefunction)

inspect.fullargspec returns a named tuple with 7 elements:

  • A list with the argument names
  • The name of the catchall *args parameter, if defined (None otherwise)
  • The name of the catchall **kwargs parameter, if defined (None otherwise)
  • A tuple with default values for the keyword arguments; they go with the last elements of the arguments; match these by length of the default values tuple.
  • A list of keyword-only parameter names
  • A dictionary of default values for the keyword-only parameter names, if any
  • and a dictionary containing the annotations

With inspect.signature() you get a Signature object, a rich object that models not only the above data as a more structured set of objects but also lets you bind values to parameters the same way a call to the function would.

Which one is better will depend on your use cases.

Demo:

>>> import inspect
>>> def foo(bar, baz, spam='eggs', *monty, python: "kwonly", spanish=42, **inquisition) -> "return annotation":
... pass
...
>>> inspect.getfullargspec(foo)
FullArgSpec(args=['bar', 'baz', 'spam'], varargs='monty', varkw='inquisition', defaults=('eggs',), kwonlyargs=['python', 'spanish'], kwonlydefaults={'spanish': 42}, annotations={'return': 'return annotation', 'python': 'kwonly'})
>>> signature = inspect.signature(foo)
>>> signature
<Signature (bar, baz, spam='eggs', *monty, python: 'kwonly', spanish=42, **inquisition) -> 'return annotation'>
>>> signature.parameters['python'].kind.description
'keyword-only'
>>> signature.bind('Eric', 'Idle', 'John', python='Cleese')
<BoundArguments (bar='Eric', baz='Idle', spam='John', python='Cleese')>

If you have a dictionary named values of possible parameter values, I'd use inspect.signature() and use the Signature.parameters mapping to match names:

posargs = [
values[param.name]
for param in signature.parameters.values()
if param.kind is Parameter.POSITIONAL_ONLY
]
skip_kinds = {Parameter.POSITIONAL_ONLY, Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD}
kwargs = {
param.name: values[param.name]
for param in signature.parameters.values()
if param.name in values and param.kind not in skip_kinds
}

The above gives you a list of values for the positional-only parameters, and a dictionary for the rest (excepting any *args or **kwargs parameters).

Get a list/tuple/dict of the arguments passed to a function?

You can use locals() to get a dict of the local variables in your function, like this:

def foo(a, b, c):
print locals()

>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}

This is a bit hackish, however, as locals() returns all variables in the local scope, not only the arguments passed to the function, so if you don't call it at the very top of the function the result might contain more information than you want:

def foo(a, b, c):
x = 4
y = 5
print locals()

>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}

I would rather construct a dict or list of the variables you need at the top of your function, as suggested in the other answers. It's more explicit and communicates the intent of your code in a more clear way, IMHO.



Related Topics



Leave a reply



Submit