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
Function Name Is Undefined in Python Class
What Limitations Have Closures in Python Compared to Language X Closures
Testing Floating Point Equality
Typeerror: Str Does Not Support Buffer Interface
Getting Started with the Python Debugger, Pdb
Creating Dynamically Named Variables from User Input
Call a Python Function from Jinja2
Matplotlib: How to Plot Images Instead of Points
How to Improve the Label Placement in Scatter Plot
Fastest Way to Take a Screenshot with Python on Windows
Conda' Is Not Recognized as Internal or External Command
Why the Global Interpreter Lock
Comprehension for Flattening a Sequence of Sequences