185 lines
6.4 KiB
Plaintext
185 lines
6.4 KiB
Plaintext
|
PEP: 3102
|
|||
|
Title: Keyword-Only Arguments
|
|||
|
Version: $Revision$
|
|||
|
Last-Modified: $Date$
|
|||
|
Author: Talin <talin at acm.org>
|
|||
|
Status: Draft
|
|||
|
Type: Standards
|
|||
|
Content-Type: text/plain
|
|||
|
Created: 22-Apr-2006
|
|||
|
Python-Version: 3.0
|
|||
|
Post-History:
|
|||
|
|
|||
|
|
|||
|
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:
|
|||
|
|
|||
|
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'.
|
|||
|
|
|||
|
|
|||
|
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:
|