Use of *args and **kwargs
The syntax is the *
and **
. The names *args
and **kwargs
are only by convention but there's no hard requirement to use them.
You would use *args
when you're not sure how many arguments might be passed to your function, i.e. it allows you pass an arbitrary number of arguments to your function. For example:
>>> def print_everything(*args):
for count, thing in enumerate(args):
... print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage
Similarly, **kwargs
allows you to handle named arguments that you have not defined in advance:
>>> def table_things(**kwargs):
... for name, value in kwargs.items():
... print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit
You can use these along with named arguments too. The explicit arguments get values first and then everything else is passed to *args
and **kwargs
. The named arguments come first in the list. For example:
def table_things(titlestring, **kwargs)
You can also use both in the same function definition but *args
must occur before **kwargs
.
You can also use the *
and **
syntax when calling a function. For example:
>>> def print_three_things(a, b, c):
... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat
As you can see in this case it takes the list (or tuple) of items and unpacks it. By this it matches them to the arguments in the function. Of course, you could have a *
both in the function definition and in the function call.
What do *args and **kwargs mean?
Putting *args
and/or **kwargs
as the last items in your function definition’s argument list allows that function to accept an arbitrary number of arguments and/or keyword arguments.
For example, if you wanted to write a function that returned the sum of all its arguments, no matter how many you supply, you could write it like this:
def my_sum(*args):
return sum(args)
It’s probably more commonly used in object-oriented programming, when you’re overriding a function, and want to call the original function with whatever arguments the user passes in.
You don’t actually have to call them args
and kwargs
, that’s just a convention. It’s the *
and **
that do the magic.
The official Python documentation has a more in-depth look.
What is the purpose and use of **kwargs?
You can use **kwargs
to let your functions take an arbitrary number of keyword arguments ("kwargs" means "keyword arguments"):
>>> def print_keyword_args(**kwargs):
... # kwargs is a dict of the keyword args passed to the function
... for key, value in kwargs.iteritems():
... print "%s = %s" % (key, value)
...
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe
You can also use the **kwargs
syntax when calling functions by constructing a dictionary of keyword arguments and passing it to your function:
>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith
The Python Tutorial contains a good explanation of how it works, along with some nice examples.
Python 3 update
For Python 3, instead of iteritems()
, use items()
What does *arg and **kwargs mean when passed through a constructor?
For single inheritance, your understanding of the behavior of super is essentially correct - you don't really need super when all you're dealing with is single inheritance.
For multiple inheritance it is not correct. There super will call the next class in self's MRO chain - which could be the parent, and could be a sibling class in case of diamond pattern inheritance.
Diamond inheritance pattern:
class A:
def say(self):
print('a')
class B(A):
def say(self):
super().say()
print('b')
class C(A):
def say(self):
super().say()
print('c')
class D(B, C):
def say(self):
super().say()
print('d')
d = D()
d.say()
the inhertiance graph looks like a diamond:
which prints
a
c
b
d
because the super in D calls B.say, which uses super to call C.say, which uses super to call A.say. I.e. the super call in B calls a class that B doesn't know about.
Need help understanding some Python code with @, *args and **kwargs
In this particular case assert_case_sensitive
is a function wrapping function, otherwise known as a decorator.
A decorator takes an existing function and returns a different function. Usually it returns a new function that calls the original function in some way. In this case assert_case_insensitive
always returns wrapper
which is a function that's defined within it who's name is only known inside assert_case_insensitive
.
When a function is declared in the body of another like that, the enclosed function is sort of created anew every time the outer function is called. This means the inner function has access to the variables from the function it was in.
This technique is called a closure, and Python's support of closures is incomplete because the variables from the enclosing scopes cannot be modified. But that's not terribly relevant to this question.
The goal of assert_case_insensitive
is to enforce some conditions on the arguments to the functions it's passed. It returns a new function that enforces those conditions and calls the original function. In order for assert_case_insensitive
to be able to be used to wrap any function, it needs to work for functions with different numbers of arguments, and functions that have keyword arguments. This is where *args
and **kargs
come in.
An argument of the form *something
gets a tuple of any remaining non-keyword (aka positional) arguments that are not accounted for by the previous positional arguments. An argument of the form **something
gets a dictionary any remaining keyword arguments that are not accounted for by the previous positional arguments. Arguments of the form *something
or **something
must occur after all other arguments.
A similar syntax is used for calling functions with argument lists that aren't know. An argument of the form *(iterable sequence)
is turned into a series of positional arguments, and an argument of the form **(dictionary)
is turned into a set of keyword arguments.
So wrapper
is using these constructs so it can work very generally for any function. Decorators in general are expected to work for any function, so doing something like this is highly recommended when writing them.
When do I use **kwargs vs kwargs (*args vs args)?
Here's a sample function signature:
def foo(a, b, *args, **kwargs):
Here *args
represents the arguments after a
and b
that aren't required, are passed like 'non-named' arguments (foo(1, 2, 3, 4, 5)
) and the function gets them as a tuple called args
: args == (3, 4, 5)
.
**kwargs
represents the arguments that aren't required, are passed by name (foo(1, 2, foo=3, bar=4)
) and the function gets them as a dictionary called kwargs
: kwargs == {'foo': 3, 'bar': 4}
.
When you use the star notation outside function definition, it tries to extract data from a tuple or a dictionary, e.g. *(1, 2, 3)
gives you three separate values that have been extracted from the tuple, *{'foo': 5}
will extract all the keys of the dictionary, but foo(**{'foo': 5, 'bar': 6})
will attempt to pass two arguments called foo
and bar
with values 5
and 6
respectively to the function foo
.
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
The *args
and **kwargs
is a common idiom to allow arbitrary number of arguments to functions as described in the section more on defining functions in the Python documentation.
The *args
will give you all function parameters as a tuple:
def foo(*args):
for a in args:
print(a)
foo(1)
# 1
foo(1,2,3)
# 1
# 2
# 3
The **kwargs
will give you all
keyword arguments except for those corresponding to a formal parameter as a dictionary.
def bar(**kwargs):
for a in kwargs:
print(a, kwargs[a])
bar(name='one', age=27)
# name one
# age 27
Both idioms can be mixed with normal arguments to allow a set of fixed and some variable arguments:
def foo(kind, *args, **kwargs):
pass
It is also possible to use this the other way around:
def foo(a, b, c):
print(a, b, c)
obj = {'b':10, 'c':'lee'}
foo(100,**obj)
# 100 10 lee
Another usage of the *l
idiom is to unpack argument lists when calling a function.
def foo(bar, lee):
print(bar, lee)
l = [1,2]
foo(*l)
# 1 2
In Python 3 it is possible to use *l
on the left side of an assignment (Extended Iterable Unpacking), though it gives a list instead of a tuple in this context:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
Also Python 3 adds new semantic (refer PEP 3102):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
For example the following works in python 3 but not python 2:
>>> x = [1, 2]
>>> [*x]
[1, 2]
>>> [*x, 3, 4]
[1, 2, 3, 4]
>>> x = {1:1, 2:2}
>>> x
{1: 1, 2: 2}
>>> {**x, 3:3, 4:4}
{1: 1, 2: 2, 3: 3, 4: 4}
Such function accepts only 3 positional arguments, and everything after *
can only be passed as keyword arguments.
Note:
- A Python
dict
, semantically used for keyword argument passing, are arbitrarily ordered. However, in Python 3.6, keyword arguments are guaranteed to remember insertion order. - "The order of elements in
**kwargs
now corresponds to the order in which keyword arguments were passed to the function." - What’s New In Python 3.6 - In fact, all dicts in CPython 3.6 will remember insertion order as an implementation detail, this becomes standard in Python 3.7.
*args and **kwargs Python
The decorator can be written a bit more clearly to not use args[0]
, does this help you understand?
def authenticated(fn):
def wrapper(user, *args, **kwargs):
if user['valid']:
return fn(user, *args, **kwargs)
return wrapper
@authenticated
def message_friends(user):
print('message has been sent to', user['name'])
message_friends({'name': 'Sorna', 'valid': True})
message_friends({'name': 'Bob', 'valid': False})
Now *args, **kwargs
is only there to pass along any other arguments the decorated function might have.
This is also more robust because it works whether user
is passed positionally or as a keyword argument.
python *args and **kwargs
Pass the *args
and **kwargs
to your function not the argument(s) and named argument(s):
def test1(*args,**kwargs):
return moving_average(*args, **kwargs)
Related Topics
Pytest - Specify Log Level from the Cli Command Running the Tests
Differencebetween "Is None" and "== None"
Creating a JSON Response Using Django and Python
What's the Difference Between Globals(), Locals(), and Vars()
Pythonic Way to Print List Items
How to Specify Multiple Return Types Using Type-Hints
Python: List VS Dict for Look Up Table
How to Enable Cors on Django Rest Framework
Output to the Same Line Overwriting Previous Output
Order' of Unordered Python Sets
Import CSV File as a Pandas Dataframe
Can't Set Attributes on Instance of "Object" Class
How to Ignore the First Line of Data When Processing CSV Data
How to Pass Another Entire Column as Argument to Pandas Fillna()