191 lines
6.7 KiB
Plaintext
191 lines
6.7 KiB
Plaintext
PEP: 3102
|
||
Title: Keyword-Only Arguments
|
||
Version: $Revision$
|
||
Last-Modified: $Date$
|
||
Author: Talin <viridia@gmail.com>
|
||
Status: Final
|
||
Type: Standards Track
|
||
Content-Type: text/plain
|
||
Created: 22-Apr-2006
|
||
Python-Version: 3.0
|
||
Post-History: 28-Apr-2006, May-19-2006
|
||
|
||
|
||
Abstract
|
||
|
||
This PEP proposes a change to the way that function arguments are
|
||
assigned to named parameter slots. In particular, it enables the
|
||
declaration of "keyword-only" arguments: arguments that can only
|
||
be supplied by keyword and which will never be automatically
|
||
filled in by a positional argument.
|
||
|
||
|
||
Rationale
|
||
|
||
The current Python function-calling paradigm allows arguments to
|
||
be specified either by position or by keyword. An argument can be
|
||
filled in either explicitly by name, or implicitly by position.
|
||
|
||
There are often cases where it is desirable for a function to take
|
||
a variable number of arguments. The Python language supports this
|
||
using the 'varargs' syntax ('*name'), which specifies that any
|
||
'left over' arguments be passed into the varargs parameter as a
|
||
tuple.
|
||
|
||
One limitation on this is that currently, all of the regular
|
||
argument slots must be filled before the vararg slot can be.
|
||
|
||
This is not always desirable. One can easily envision a function
|
||
which takes a variable number of arguments, but also takes one
|
||
or more 'options' in the form of keyword arguments. Currently,
|
||
the only way to do this is to define both a varargs argument,
|
||
and a 'keywords' argument (**kwargs), and then manually extract
|
||
the desired keywords from the dictionary.
|
||
|
||
|
||
Specification
|
||
|
||
Syntactically, the proposed changes are fairly simple. The first
|
||
change is to allow regular arguments to appear after a varargs
|
||
argument:
|
||
|
||
def sortwords(*wordlist, case_sensitive=False):
|
||
...
|
||
|
||
This function accepts any number of positional arguments, and it
|
||
also accepts a keyword option called 'case_sensitive'. This
|
||
option will never be filled in by a positional argument, but
|
||
must be explicitly specified by name.
|
||
|
||
Keyword-only arguments are not required to have a default value.
|
||
Since Python requires that all arguments be bound to a value,
|
||
and since the only way to bind a value to a keyword-only argument
|
||
is via keyword, such arguments are therefore 'required keyword'
|
||
arguments. Such arguments must be supplied by the caller, and
|
||
they must be supplied via keyword.
|
||
|
||
The second syntactical change is to allow the argument name to
|
||
be omitted for a varargs argument. The meaning of this is to
|
||
allow for keyword-only arguments for functions that would not
|
||
otherwise take a varargs argument:
|
||
|
||
def compare(a, b, *, key=None):
|
||
...
|
||
|
||
The reasoning behind this change is as follows. Imagine for a
|
||
moment a function which takes several positional arguments, as
|
||
well as a keyword argument:
|
||
|
||
def compare(a, b, key=None):
|
||
...
|
||
|
||
Now, suppose you wanted to have 'key' be a keyword-only argument.
|
||
Under the above syntax, you could accomplish this by adding a
|
||
varargs argument immediately before the keyword argument:
|
||
|
||
def compare(a, b, *ignore, key=None):
|
||
...
|
||
|
||
Unfortunately, the 'ignore' argument will also suck up any
|
||
erroneous positional arguments that may have been supplied by the
|
||
caller. Given that we'd prefer any unwanted arguments to raise an
|
||
error, we could do this:
|
||
|
||
def compare(a, b, *ignore, key=None):
|
||
if ignore: # If ignore is not empty
|
||
raise TypeError
|
||
|
||
As a convenient shortcut, we can simply omit the 'ignore' name,
|
||
meaning 'don't allow any positional arguments beyond this point'.
|
||
|
||
(Note: After much discussion of alternative syntax proposals, the
|
||
BDFL has pronounced in favor of this 'single star' syntax for
|
||
indicating the end of positional parameters.)
|
||
|
||
|
||
Function Calling Behavior
|
||
|
||
The previous section describes the difference between the old
|
||
behavior and the new. However, it is also useful to have a
|
||
description of the new behavior that stands by itself, without
|
||
reference to the previous model. So this next section will
|
||
attempt to provide such a description.
|
||
|
||
When a function is called, the input arguments are assigned to
|
||
formal parameters as follows:
|
||
|
||
- For each formal parameter, there is a slot which will be used
|
||
to contain the value of the argument assigned to that
|
||
parameter.
|
||
|
||
- Slots which have had values assigned to them are marked as
|
||
'filled'. Slots which have no value assigned to them yet are
|
||
considered 'empty'.
|
||
|
||
- Initially, all slots are marked as empty.
|
||
|
||
- Positional arguments are assigned first, followed by keyword
|
||
arguments.
|
||
|
||
- For each positional argument:
|
||
|
||
o Attempt to bind the argument to the first unfilled
|
||
parameter slot. If the slot is not a vararg slot, then
|
||
mark the slot as 'filled'.
|
||
|
||
o If the next unfilled slot is a vararg slot, and it does
|
||
not have a name, then it is an error.
|
||
|
||
o Otherwise, if the next unfilled slot is a vararg slot then
|
||
all remaining non-keyword arguments are placed into the
|
||
vararg slot.
|
||
|
||
- For each keyword argument:
|
||
|
||
o If there is a parameter with the same name as the keyword,
|
||
then the argument value is assigned to that parameter slot.
|
||
However, if the parameter slot is already filled, then that
|
||
is an error.
|
||
|
||
o Otherwise, if there is a 'keyword dictionary' argument,
|
||
the argument is added to the dictionary using the keyword
|
||
name as the dictionary key, unless there is already an
|
||
entry with that key, in which case it is an error.
|
||
|
||
o Otherwise, if there is no keyword dictionary, and no
|
||
matching named parameter, then it is an error.
|
||
|
||
- Finally:
|
||
|
||
o If the vararg slot is not yet filled, assign an empty tuple
|
||
as its value.
|
||
|
||
o For each remaining empty slot: if there is a default value
|
||
for that slot, then fill the slot with the default value.
|
||
If there is no default value, then it is an error.
|
||
|
||
In accordance with the current Python implementation, any errors
|
||
encountered will be signaled by raising TypeError. (If you want
|
||
something different, that's a subject for a different PEP.)
|
||
|
||
|
||
Backwards Compatibility
|
||
|
||
The function calling behavior specified in this PEP is a superset
|
||
of the existing behavior - that is, it is expected that any
|
||
existing programs will continue to work.
|
||
|
||
|
||
Copyright
|
||
|
||
This document has been placed in the public domain.
|
||
|
||
|
||
Local Variables:
|
||
mode: indented-text
|
||
indent-tabs-mode: nil
|
||
sentence-end-double-space: t
|
||
fill-column: 70
|
||
coding: utf-8
|
||
End:
|