How to Read a Function's Signature Including Default Argument Values

How can I read a function's signature including default argument values?

import inspect

def foo(a, b, x='blah'):
pass

print(inspect.signature(foo))
# (a, b, x='blah')

Python 3.5+ recommends inspect.signature().

How to check if default value for python function argument is set using inspect?

You can do it like this:

import inspect

def foo(a, b=1):
pass

for param in inspect.signature(foo).parameters.values():
if param.default is param.empty:
print(param.name)

Output:

a

param.empty holds the same object inspect._empty. I suppose that this way of using it is recommended because of the example in the official documentation of inspect module:

Example: print all keyword-only arguments without default values:

>>>
>>> def foo(a, b, *, c, d=10):
... pass

>>> sig = signature(foo)
>>> for param in sig.parameters.values():
... if (param.kind == param.KEYWORD_ONLY and
... param.default is param.empty):
... print('Parameter:', param)
Parameter: c

How does one read the function signatures from Python's official documentation

The asterisk in the example below means that key and default are keyword only arguments:

min(iterable, *[, key, default])

Parameter in square brackets are optional, so below filename is optional:

readline.append_history_file(nelements[, filename])

Argument with a single asterisk mean that the function can have any number of positional arguments, for instance:

a_function(a, b, *args)

Argument with 2 asterisks mean that the function can have any number of keyword arguments, for instance:

class dict(mapping, **kwarg)

Everything is explained in the Python documentation: Function definitions

How to see function signature in Python?

help(the_funcion) should give you all of that information.

Sample:

>>> help(enumerate)
Help on class enumerate in module __builtin__:

class enumerate(object)
| enumerate(iterable[, start]) -> iterator for index, value of iterable
|
| Return an enumerate object. iterable must be another object that supports
| iteration. The enumerate object yields pairs containing a count (from
| start, which defaults to zero) and a value yielded by the iterable argument
| enumerate is useful for obtaining an indexed list:
| (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
|
| Methods defined here:
|
| __getattribute__(...)
| x.__getattribute__('name') <==> x.name
|
| __iter__(...)
| x.__iter__() <==> iter(x)
|
| next(...)
| x.next() -> the next value, or raise StopIteration
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __new__ = <built-in method __new__ of type object>
| T.__new__(S, ...) -> a new object with type S, a subtype of T

Get a function argument's default value?

Python3.x

In a python3.x world, you should probably use a Signature object:

import inspect

def get_default_args(func):
signature = inspect.signature(func)
return {
k: v.default
for k, v in signature.parameters.items()
if v.default is not inspect.Parameter.empty
}

Python2.x (old answer)

The args/defaults can be combined as:

import inspect
a = inspect.getargspec(eat_dog)
zip(a.args[-len(a.defaults):],a.defaults)

Here a.args[-len(a.defaults):] are the arguments with defaults values and obviously a.defaults are the corresponding default values.

You could even pass the output of zip to the dict constructor and create a mapping suitable for keyword unpacking.


looking at the docs, this solution will only work on python2.6 or newer since I assume that inspect.getargspec returns a named tuple. Earlier versions returned a regular tuple, but it would be very easy to modify accordingly. Here's a version which works with older (and newer) versions:

import inspect
def get_default_args(func):
"""
returns a dictionary of arg_name:default_values for the input function
"""
args, varargs, keywords, defaults = inspect.getargspec(func)
return dict(zip(args[-len(defaults):], defaults))

Come to think of it:

    return dict(zip(reversed(args), reversed(defaults)))

would also work and may be more intuitive to some people.


How to retrieve/know function's default values

cv2.ORB_create() seems to be a function written with the Python extensions (In C instead of Python). As such, it isn't a "normal" function object, and there is no way to see the default values reliably (As it is handled manually in C).

One possible solution would be to look at the __text_signature__ attribute, but this may not be reliable. See What are __signature__ and __text_signature__ used for in Python 3.4.

How to return default values with *args, and **kwargs in function signature

*args only captures any positional arguments not otherwise defined; y=10 does not mean y can't be used as a positional argument. So y is assigned the first positional argument.

You can prevent y being used as a positional argument by making it a keyword-only argument. You do this by placing the argument after the *args var-positional catch-all parameter, or if you don't have a *name parameter, after a * single asterisk:

def add_args(*args, y=10, **kwargs):
return y, args, kwargs

or

def keyword_only_args(*, y=10, **kwargs):
return y, kwargs

Now y won't capture positional arguments any more:

>>> def add_args(*args, y=10, **kwargs):
... return y, args, kwargs
...
>>> add_args(1, 5, 10, 20, 50)
(10, (1, 5, 10, 20, 50), {}) # y is still 10
>>> add_args(1, 5, 10, 20, 50, y=42) # setting y explicitly
(42, (1, 5, 10, 20, 50), {})

You don't have to have a **kwargs keyword catch-all either:

def add_args(*args, y=10):
return y, args

but if it is present, it needs to be listed last.

Keyword-only arguments do not have to have a default value, the =10 can be omitted, but then the parameter becomes mandatory, and can only be specified in a call by using y=value:

>>> def add_args(*args, y):  # mandatory keyword-only argument
... return y, args
...
>>> add_args(1, 5, 10, 20, 50)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add_args() missing 1 required keyword-only argument: 'y'
>>> add_args(1, 5, 10, 20, 50, y=42)
(42, (1, 5, 10, 20, 50))

How to check which arguments a function/method takes?

You can use inspect.getargspec() to see what arguments are accepted, and any default values for keyword arguments.

Demo:

>>> def foo(bar, baz, spam='eggs', **kw): pass
...
>>> import inspect
>>> inspect.getargspec(foo)
ArgSpec(args=['bar', 'baz', 'spam'], varargs=None, keywords='kw', defaults=('eggs',))
>>> inspect.getargspec(foo).args
['bar', 'baz', 'spam']

In Python 3, you want to use inspect.getfullargspec() as this method supports new Python 3 function argument features:

>>> def foo(bar: str, baz: list, spam: str = 'eggs', *, monty: str = 'python', **kw) -> None: pass
...
>>> import inspect
>>> inspect.getfullargspec(foo)
FullArgSpec(args=['bar', 'baz', 'spam'], varargs=None, varkw='kw', defaults=('eggs',), kwonlyargs=['monty'], kwonlydefaults={'monty': 'python'}, annotations={'baz': <class 'list'>, 'return': None, 'spam': <class 'str'>, 'monty': <class 'str'>, 'bar': <class 'str'>})

inspect.getargspec() should be considered deprecated in Python 3.

Python 3.4 adds the inspect.Signature() object:

>>> inspect.signature(foo)
<inspect.Signature object at 0x100bda588>
>>> str(inspect.signature(foo))
"(bar:str, baz:list, spam:str='eggs', *, monty:str='python', **kw) -> None"
>>> inspect.signature(foo).parameters
mappingproxy(OrderedDict([('bar', <Parameter at 0x100bd67c8 'bar'>), ('baz', <Parameter at 0x100bd6ea8 'baz'>), ('spam', <Parameter at 0x100bd69f8 'spam'>), ('monty', <Parameter at 0x100bd6c28 'monty'>), ('kw', <Parameter at 0x100bd6548 'kw'>)]))

and many more interesting options to play with signatures.

Capturing a function call as dict

Whenever you want to introspect function/method signatures, you can use inspect.signature. In this case:

from inspect import signature

def decorator(func):
sig = signature(func)
def wrapper(*args, **kwargs):
bound = sig.bind(*args, **kwargs)
bound.apply_defaults()
print(bound.arguments)
return func(*args, **kwargs)
return wrapper

*args are a tuple, not a list, but otherwise this gives you what you want:

>>> print(foo(1, 2))
{'a': 1, 'b': 2, '_': (), 'kwargs': {}}
3

How do I get a function's full name and arguments as string from a list of function objects in Python?

Although it is not perfect, how about using inspect.signature?

from inspect import getmembers, isfunction, signature
import numpy

def explain(m):
try:
return f"{m[0]}{signature(m[1])}"
except ValueError:
return f"{m[0]}(???)" # some functions don't provide a signature

print(*(explain(m) for m in getmembers(numpy, isfunction)), sep='\n')

# __dir__()
# __getattr__(attr)
# add_newdoc(place, obj, doc, warn_on_python=True)
# alen(a)
# all(a, axis=None, out=None, keepdims=<no value>, *, where=<no value>)


Related Topics



Leave a reply



Submit