Functions and methods written in Python can now be called using
keyword arguments of the form keyword = value
. For
instance, the following function:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): print "-- This parrot wouldn't", action, print "if you put", voltage, "Volts through it." print "-- Lovely plumage, the", type print "-- It's", state, "!"
could be called in any of the following ways:
parrot(1000) parrot(action = 'VOOOOOM', voltage = 1000000) parrot('a thousand', state = 'pushing up the daisies') parrot('a million', 'bereft of life', 'jump')
but the following calls would all be invalid:
parrot() # required argument missing parrot(voltage=5.0, 'dead') # non-keyword argument following keyword parrot(110, voltage=220) # duplicate value for argument parrot(actor='John Cleese') # unknown keyword
In general, an argument list must have the form: zero or more positional arguments followed by zero or more keyword arguments, where the keywords must be chosen from the formal parameter names. It's not important whether a formal parameter has a default value or not. No argument must receive a value more than once -- formal parameter names corresponding to positional arguments cannot be used as keywords in the same calls.
Note that no special syntax is required to allow a function to be called with keyword arguments. The additional costs incurred by keyword arguments are only present when a call uses them.
(As far as I know, these rules are exactly the same as used by Modula-3, even if they are enforced by totally different means. This is intentional.)
When a final formal parameter of the form **name
is
present, it receives a dictionary containing all keyword arguments
whose keyword doesn't correspond to a formal parameter. This may be
combined with a formal parameter of the form *name
which
receives a tuple containing the positional arguments beyond the formal
parameter list. (*name
must occur before
**name
.) For example, if we define a function like this:
def cheeseshop(kind, *arguments, **keywords): print "-- Do you have any", kind, '?' print "-- I'm sorry, we're all out of", kind for arg in arguments: print arg print '-'*40 for kw in keywords.keys(): print kw, ':', keywords[kw]
It could be called like this:
cheeseshop('Limburger', "It's very runny, sir.", "It's really very, VERY runny, sir.", client='John Cleese', shopkeeper='Michael Palin', sketch='Cheese Shop Sketch')
and of course it would print:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch
Consequences of this change include:
apply()
now has an optional third
argument, which is a dictionary specifying any keyword arguments to be
passed. For example,
apply(parrot, (), {'voltage': 20, 'action': 'voomm'})is equivalent to
parrot(voltage=20, action='voomm')
.pyc
files has changed (again).access
statement has been disabled. The syntax is still
recognized but no code is generated for it. (There were some
unpleasant interactions with changes for keyword arguments, and my
plan is to get rid of access
altogether in favor of a different
approach.)