*args passes variable number of non-keyworded arguments and on which operation of the tuple can be performed. **kwargs passes variable number of keyword arguments dictionary to function on which operation of a dictionary can be performed.
**kwargs stands for keyword arguments. The only difference from args is that it uses keywords and returns the values in the form of a dictionary.
Python is pretty flexible in terms of how arguments are passed to a function. The *args and **kwargs make it easier and cleaner to handle arguments. The important parts are “*” and “**”. You can use any word instead of args and kwargs but it is the common practice to use the words args and kwargs.
Using *args and **kwargs in Function Calls The function will print out each of these arguments. We then create a variable that is set to an iterable (in this case, a tuple), and can pass that variable into the function with the asterisk syntax.
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.
Also, we use them for managing inheritance.
class Super( object ):
def __init__( self, this, that ):
self.this = this
self.that = that
class Sub( Super ):
def __init__( self, myStuff, *args, **kw ):
super( Sub, self ).__init__( *args, **kw )
self.myStuff= myStuff
x= Super( 2.7, 3.1 )
y= Sub( "green", 7, 6 )
This way Sub doesn't really know (or care) what the superclass initialization is. Should you realize that you need to change the superclass, you can fix things without having to sweat the details in each subclass.
Notice the cool thing in S.Lott's comment - you can also call functions with *mylist
and **mydict
to unpack positional and keyword arguments:
def foo(a, b, c, d):
print a, b, c, d
l = [0, 1]
d = {"d":3, "c":2}
foo(*l, **d)
Will print: 0 1 2 3
Another good use for *args
and **kwargs
: you can define generic "catch all" functions, which is great for decorators where you return such a wrapper instead of the original function.
An example with a trivial caching decorator:
import pickle, functools
def cache(f):
_cache = {}
def wrapper(*args, **kwargs):
key = pickle.dumps((args, kwargs))
if key not in _cache:
_cache[key] = f(*args, **kwargs) # call the wrapped function, save in cache
return _cache[key] # read value from cache
functools.update_wrapper(wrapper, f) # update wrapper's metadata
return wrapper
import time
@cache
def foo(n):
time.sleep(2)
return n*2
foo(10) # first call with parameter 10, sleeps
foo(10) # returns immediately
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With