Positional argument v.s. keyword argument
Solution 1:
That text you quote seems to be confused about two totally different things:
- Positional and keyword arguments are a feature of calls to a function (see Python reference section
5.3.4 Calls
). - Default values are a feature of function definitions, as per section
7.6 Function definitions
I suspect the people who put together that course-ware weren't totally familiar with Python :-) Hence that link you provide is not a very good quality one.
In your call to your function, you're using the "keyword argument" feature (where the argument is named rather than relying on its position). Without that, values are bound to names based on order alone. So, in this example, the two calls below are equivalent:
def process_a_and_b(a, b):
blah_blah_blah()
process_a_and_b(1, 2)
process_a_and_b(b=2, a=1)
By further way of example, refer to the following definition and calls:
def fn(a, b, c=1): # a/b required, c optional.
return a * b + c
print(fn(1, 2)) # returns 3, positional and default.
print(fn(1, 2, 3)) # returns 5, positional.
print(fn(c=5, b=2, a=2)) # returns 9, named.
print(fn(b=2, a=2)) # returns 5, named and default.
print(fn(5, c=2, b=1)) # returns 7, positional and named.
print(fn(8, b=0)) # returns 1, positional, named and default.
Solution 2:
Since Python 3.8 introduced positional-only parameters, this post needed an update.
Positional arguments, keyword arguments, required arguments and optional arguments are often confused. Positional arguments ARE NOT THE SAME AS required arguments, and keywords arguments ARE NOT THE SAME AS optional arguments.
Positional arguments are arguments that can be called by their position in the function definition.
Keyword arguments are arguments that can be called by their name.
Required arguments are arguments that must passed to the function.
Optional arguments are arguments that can be not passed to the function. In Python, optional arguments are arguments that have a default value.
-
Positional argument that is optional (Python 3.8)
def f(a=2, /): pass f() # Allowed, argument is optional f(1) # Allowed, it's a positional argument f(a=1) # Error, positional only argument
-
Positional argument that is required (Python 3.8)
def f(a, /): pass f() # Error, argument required f(1) # Allowed, it's a positional argument f(a=1) # Error, positional only argument
-
Keyword argument that is optional
def f(*, a=1): pass f() # Allowed f(1) # Error, keyword only arguments f(a=1) # Allowed, it's a keyword argument
-
Keyword argument that is required
def f(*, a) pass f() # Error, argument required f(1) # Error, keyword only arguments f(a=1) # Allowed, it's a keyword argument
-
Positional-or-keyword argument that is optional
def f(a=1) pass f() # Allowed, argument is optional f(1) # Allowed, it's a positional argument f(a=1) # Allowed, it's a keyword argument # In fact this function is the same as def f(/, a=1, *): pass
-
Positional-or-keyword argument that is required
def f(a): pass f() # Error, argument required f(1) # Allowed, it's a positional argument f(a=1) # Allowed, it's a keyword argument # In fact this function is the same as def f(/, a, *): pass
Conclusion, an argument can be optional or required but not both at the same time. It can also be positional, keyword or both at the same time.
Python 3.8 introduced positional-only parameters.
def f(positional_argument, /, positional_or_keyword_argument, *, keyword_argument):
pass