Is a complex answer by using the * like the argument ( the Python version, define and use it ).
In your case:
>>> foo(1,2,)
>>> foo(1,2)
Note that:
Try to use this and see the difference ( without self ):
>>> def foo( arg1=1, *, arg2=2):
... pass
...
>>> foo(arg1=1,arg2=2)
>>> def foo( arg1=1, *, arg2=2):
... pass
...
>>> foo(arg1=1,arg2=2)
>>> foo(arg1=1)
>>> foo(arg1=1,)
>>> foo(arg2=2)
>>> foo(arg2=2,1)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> foo(2,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes from 0 to 1 positional arguments but 2 were given
>>> foo(arg1=1,2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
- One star * defines positional arguments (you can receive any number of arguments and treat the passed arguments as a tuple);
- Two stars ** define keywords arguments.
A good example comes from this tutorial (the keyword-only arguments without positional arguments part):
def with_previous(iterable, *, fillvalue=None):
"""Yield each iterable item along with the item before it."""
previous = fillvalue
for item in iterable:
yield previous, item
previous = item
>>> list(with_previous([2, 1, 3], fillvalue=0))
[(0, 2), (2, 1), (1, 3)]
That its value could be sent as positional arguments.
See this tutorial for more info about arguments.
Python 3.x introduces more intuitive keyword-only arguments with PEP-3102 (you can specify * in the argument list).
One good alternative answer is this: