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.
Videos
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.
One place where the use of *args and **kwargs is quite useful is for subclassing.
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2
class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)
This way you can extend the behaviour of the Foo class, without having to know too much about Foo. This can be quite convenient if you are programming to an API which might change. MyFoo just passes all arguments to the Foo class.
Hello everyone, I hope you all are doing well. Iโm confused about these keywords in Python and what they do and where I can use them, since am new to python.
Anyone?
In addition to the accepted answer (which raises some good points), you also have to consider how your function is going to be used. Using os.path.join as an example, it makes sense for this function to accept *args because one is going to often be dealing with a set number of path elements, where each one might have its own name. For example:
dir_name = os.getcwd()
temp_folder = 'temp'
base_name = 'base_file.txt'
full_path = os.path.join(dir_name, temp_folder, base_name)
On the other hand, when you are working with indistinguishable elements that are naturally going to be grouped into a container object, it makes more sense to use args. Consider the following usage with str.join.
sentence = 'this is an example sentence'
words = sentence.split()
dash_separated = '-'.join(words)
Yes it's fine to use *args here.
You should use *args when it's easier to read than a list of argument (def foo(a,b,c,d,e...)) and does not make harder to know which argument is used for what.
Your example is the perfect example of a good usage of *args, all elements within args will be processed in the exacte same way.
You should avoid it when you need to perform different compute for each argument, like:
def foo(*args):
do_one_stuff(args[1], args[2])
if args[3]:
do_another_stuff(args[3], args[4])
if args[6] != args[7]:
return args[0]
else:
return None
This example should make you feel what a function could be if you make a bad usage of *args.