Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default arguments with *args and **kwargs

People also ask

What are the 3 types of arguments in Python?

Hence, we conclude that Python Function Arguments and its three types of arguments to functions. These are- default, keyword, and arbitrary arguments.

What is default argument in Python with example?

Python Default Arguments Here is an example. def greet(name, msg="Good morning!"): """ This function greets to the person with the provided message. If the message is not provided, it defaults to "Good morning!" """ print("Hello", name + ', ' + msg) greet("Kate") greet("Bruce", "How do you do?")

What are the 4 types of arguments in Python?

5 Types of Arguments in Python Function Definition:positional arguments. arbitrary positional arguments. arbitrary keyword arguments.

What is a default argument in C++?

A default argument is a value provided in a function declaration that is automatically assigned by the compiler if the calling function doesn't provide a value for the argument. In case any value is passed, the default value is overridden.


Just put the default arguments before the *args:

def foo(a, b=3, *args, **kwargs):

Now, b will be explicitly set if you pass it as a keyword argument or the second positional argument.

Examples:

foo(x) # a=x, b=3, args=(), kwargs={}
foo(x, y) # a=x, b=y, args=(), kwargs={}
foo(x, b=y) # a=x, b=y, args=(), kwargs={}
foo(x, y, z, k) # a=x, b=y, args=(z, k), kwargs={}
foo(x, c=y, d=k) # a=x, b=3, args=(), kwargs={'c': y, 'd': k}
foo(x, c=y, b=z, d=k) # a=x, b=z, args=(), kwargs={'c': y, 'd': k}

Note that, in particular, foo(x, y, b=z) doesn't work because b is assigned by position in that case.


This code works in Python 3 too. Putting the default arg after *args in Python 3 makes it a "keyword-only" argument that can only be specified by name, not by position. If you want a keyword-only argument in Python 2, you can use @mgilson's solution.


The syntax in the other question is python3.x only and specifies keyword only arguments. It doesn't work on python2.x.

For python2.x, I would pop it out of kwargs:

def func(arg1, arg2, *args, **kwargs):
    opt_arg = kwargs.pop('opt_arg', 'def_val')

Similar approach to @yaccob, but clear and concise:

In Python 3.5 or greater:

def foo(a, b=3, *args, **kwargs):
  defaultKwargs = { 'c': 10, 'd': 12 }
  kwargs = { **defaultKwargs, **kwargs }
  print(a, b, args, kwargs)
  
  # Do something    

foo(1) # 1 3 () {'c': 10, 'd': 12}
foo(1, d=5) # 1 3 () {'c': 10, 'd': 5}
foo(1, 2, 4, d=5) # 1 2 (4,) {'c': 10, 'd': 5}

Note: you can use In Python 2

kwargs = merge_two_dicts(defaultKwargs, kwargs)

In Python 3.5

kwargs = { **defaultKwargs, **kwargs }

In Python 3.9

kwargs = defaultKwargs | kwargs  # NOTE: 3.9+ ONLY

You could also use a decorator like this:

import functools
def default_kwargs(**defaultKwargs):
    def actual_decorator(fn):
        @functools.wraps(fn)
        def g(*args, **kwargs):
            defaultKwargs.update(kwargs)
            return fn(*args, **defaultKwargs)
        return g
    return actual_decorator

Then just do:

@default_kwargs(defaultVar1 = defaultValue 1, ...)
def foo(*args, **kwargs):
    # Anything in here

For instance:

@default_kwargs(a=1)
def f(*args, **kwargs):
    print(kwargs['a']+ 1)

f() # Returns 2
f(3) # Returns 4