You can do the following:
def myF(a, b=None):
if b is None:
b = a - 1
return a * b - 2 * b
Answer from Selcuk on Stack OverflowPython: default value of function as a function argument - Stack Overflow
Python Function Default Values
Today I re-learned: Python function default arguments are retained between executions
What the default arguments are?
You can do the following:
def myF(a, b=None):
if b is None:
b = a - 1
return a * b - 2 * b
If you need to have the value of b be a function of a, but you might need that function to change, you can set the default value of b to be a lambda function and then check if b is callable in the function block.
def myF(a, b=lambda a: a-1):
if callable(b):
b = b(a)
return a * b - 2 * b
This allows you to set a different function for b on the fly as well.
# pass b as an integer
myF(1, 1)
# returns: -1
# use default function for b
myF(4)
# returns: 6
# set b to be 2*a + 1
myF(3, lambda a: 2*a+1)
# returns: 7
Say I have a function defined like
def f(foo: str, bar: str | None = "world"):
print(f"{foo} {bar})
s = None
f("hello") # prints "hello world"
f("hello", s) # prints "hello None"
Is there a data type (or concept) in Python that would enable the second function call to print "hello world" as well? In other words, bar should take on its default value. In javascript, passing undefined for bar would accomplish this. In Python, it seems like I would have to add a conditional to the function.
def f(foo: str, bar: str | None = "world"):
bar = bar or "world"
print(f"{foo} {bar})This isn't a major issue for me, but when a function has a lot of optional arguments with default values, it can be pretty verbose (for Python standards) to add a conditional for every optional argument.
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.
To those looking for a version to grab a specific default parameter with mgilson's answer.
value = signature(my_func).parameters['param_name'].default
Here's a full working version, done in Python 3.8.2
from inspect import signature
def my_func(a, b, c, param_name='apple'):
pass
value = signature(my_func).parameters['param_name'].default
print(value == 'apple') # True