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 can I access the default value of a function argument?
In my proposed solution, I also eliminated the rlang dependency (please see below):
default_arg <- function(arg = NULL, func = NULL) {
if(deparse(substitute(arg)) == "NULL" & is.null(func))
{
arg = sys.calls()[[1]]
val = as.character(arg); names(val) = names(arg)
func = val[1]
variable = names(which(val == "default_arg()"))
return(formals(func)[[variable]])
}
if(is.null(func))
{
func = as.character(sys.call(sys.parent()))[1]
}
return(formals(func)[[deparse(substitute(arg))]])
}
default_arg(x, tester_1) # 1
default_arg(y, tester_1) # 2
default_arg(z, tester_1) # 3
tester_2() # 5
tester_1(x = 1, y = 2, z = default_arg()) # 5
tester_1(x = 1, y = default_arg(), z = 3) # 5
tester_1(x = default_arg(), y = 2, z = 3) # 5
Basically, it is just parsing the call and extracting the relevant information.
Though this works, I am sure you can still make it neater by avoiding the conditionals. Good luck!
Best,
Ventrilocus.
Python: default value of function as a function argument
You can do the following:
def myF(a, b=None):
if b is None:
b = a - 1
return a * b - 2 * b
How to tell a function to use the default argument values?
One way to do it would be with variadic argument unpacking:
def foo(..., **kwargs):
...
if math.isclose(x, y, **kwargs):
...
This would allow you to specify atol
and rtol
as keyword arguments to the main function foo
, which it would then pass on unchanged to math.isclose
.
However, I would also say that it is idiomatic that arguments passed to kwargs
modify the behaviour of a function in some way other than to be merely passed to sub-functions being called. Therefore, I would suggest that instead, a parameter is named such that it is clear that it will be unpacked and passed unchanged to a sub-function:
def foo(..., isclose_kwargs={}):
...
if math.isclose(x, y, **isclose_kwargs):
...
You can see an equivalent pattern in matplotlib
(example: plt.subplots
- subplot_kw
and gridspec_kw
, with all other keyword arguments being passed to the Figure
constructor as **fig_kw
) and seaborn
(example: FacetGrid
- subplot_kws
, gridspec_kws
).
This is particularly apparent when there are mutiple sub-functions you might want to pass keyword arguments, but retain the default behaviour otherwise:
def foo(..., f1_kwargs={}, f2_kwargs={}, f3_kwargs={}):
...
f1(**f1_kwargs)
...
f2(**f2_kwargs)
...
f3(**f3_kwargs)
...
Caveat:
Note that default arguments are only instantiated once, so you should not modify the empty dicts
in your function. If there is a need to, you should instead use None
as the default argument and instantiate a new empty dict
each time the function is run:
def foo(..., isclose_kwargs=None):
if isclose_kwargs is None:
isclose_kwargs = {}
...
if math.isclose(x, y, **isclose_kwargs):
...
My preference is to avoid this where you know what you're doing since it is more brief, and in general I don't like rebinding variables. However, it is definitely a valid idiom, and it can be safer.
How to explicitly call the default value of a function argument in R?
You can access the argument list and default values via:
> formals(rnorm)
$n
$mean
[1] 0
$sd
[1] 1
formals("rnorm")
also works. Some simple examples:
> rnorm(10,mean = formals(rnorm)$mean)
[1] -0.5376897 0.4372421 0.3449424 -0.9569394 -1.1459726 -0.6109554 0.1907090 0.2991381 -0.2713715
[10] -1.4462570
> rnorm(10,mean = formals(rnorm)$mean + 3)
[1] 2.701544 2.863189 1.709289 2.987687 2.848045 5.136735 2.559616 3.827967 3.079658 5.016970
Obviously, you could store the result of formals(rnorm)
ahead of time as well.
Function default argument value depending on argument name in C++
According to the C++17 standard (11.3.6 Default arguments)
9 A default argument is evaluated each time the function is called
with no argument for the corresponding parameter. A parameter shall
not appear as a potentially-evaluated expression in a default
argument. Parameters of a function declared before a default
argument are in scope and can hide namespace and class member name
It provides the following example:
int h(int a, int b = sizeof(a)); // OK, unevaluated operand
So, this function declaration
void f(int y = sizeof(y)) {}
is correct because, in this expression sizeof(y)
, y
is not an evaluated operand, based on C++17 8.3.3 Sizeof:
1 The sizeof operator yields the number of bytes in the object
representation of its operand. The operand is either an expression,
which is an unevaluated operand (Clause 8), or a parenthesized
type-id.
and C++17 6.3.2 Point of declaration:
1 The point of declaration for a name is immediately after its
complete declarator (Clause 11) and before its initializer (if any),
except as noted below.
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
Related Topics
How to Avoid Explicit 'Self' in Python
Pygame.Error: Video System Not Initialized
Multiple Variables in a 'With' Statement
Prime Number Check Acts Strange
Pyqt Gui Size on High Resolution Screens
How to Do Multiple Arguments to Map Function Where One Remains the Same
Timeit Versus Timing Decorator
Python Argparse Mutual Exclusive Group
What Is the G Object in This Flask Code
Reading Unicode File Data with Bom Chars in Python
Numpy Sum Elements in Array Based on Its Value
How to Set Class Attributes from Variable Arguments (Kwargs) in Python
How to Generate a Random Number with a Specific Amount of Digits
Pandas "Can Only Compare Identically-Labeled Dataframe Objects" Error
What Happens When a Module Is Imported Twice
Difference Between Numpy Dot() and Python 3.5+ Matrix Multiplication @
When and How to Use the Builtin Function Property() in Python