Default parameter values are useful, but they still aren't enough to let us write functions like max, which can take any number of arguments at all. We could do this by requiring callers to pass a list of values, but Python can actually do this for us. Take a close look at the parameter in this function:
... '''Find the maximum of any number of values.'''
The key here is the * in front of values. This tells Python to take all the arguments passed into the call, put them in a tuple, and assign that tuple to values. For example, if we call our_max(1, 2), values is assigned (1, 2); when our_max is called with six values, values is assigned a six-element tuple, while if no arguments are provided, values is assigned an empty tuple (see Figure 12.1).
A starred parameter does not always have to appear on its own. Functions are free to define any number of regular parameters before it. These are matched up with the actual arguments as usual, and anything left over is then placed in the tuple assigned to the starred parameter:
>>> def append_all(old, *new): ... for n in new: ... old.append(n)
>>> append_all(values) # not actually appending anything [1, 2, 3]
One thing Python doesn't allow is two or more starred arguments in a single function, because matching values to them would be ambiguous. For example, if a function is defined as follows: # Illegal!
and then called with f(1,2,3), there are four possible assignments of the actual arguments to the parameters:
Python also doesn't allow "regular" parameters to be defined after a starred parameter: # Illegal!
There's no technical reason to disallow this, because Python could match actual arguments to parameters right-to-left instead of left-to-right and then put the remainder in the starred parameter. on the other hand, there's no particular reason to allow it, either. Everything that can be done this way can be done by defining the starred parameter at the end of the parameter list.
Was this article helpful?