What do *args and **kwargs mean?
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 2 Looping
--
Chapters
00:00 Question
00:38 Accepted answer (Score 276)
01:37 Answer 2 (Score 96)
02:16 Answer 3 (Score 73)
02:39 Answer 4 (Score 25)
03:22 Thank you
--
Full question
https://stackoverflow.com/questions/2870...
Accepted answer links:
[a more in-depth look]: http://docs.python.org/2/tutorial/contro...
Answer 3 links:
[S.Lott's comment]: https://stackoverflow.com/questions/2870...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python
#avk47
ACCEPTED ANSWER
Score 282
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.
ANSWER 2
Score 98
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.
ANSWER 3
Score 75
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
ANSWER 4
Score 26
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