4.7.2. 关键字参数

也可以使用形如 kwarg=value关键字参数 来调用函数。例如下面的函数:

  1. def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
  2. print("-- This parrot wouldn't", action, end=' ')
  3. print("if you put", voltage, "volts through it.")
  4. print("-- Lovely plumage, the", type)
  5. print("-- It's", state, "!")

接受一个必需的参数(voltage)和三个可选的参数(state, action,和 type)。这个函数可以通过下面的任何一种方式调用:

  1. parrot(1000) # 1 positional argument
  2. parrot(voltage=1000) # 1 keyword argument
  3. parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
  4. parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
  5. parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
  6. parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword

但下面的函数调用都是无效的:

  1. parrot() # required argument missing
  2. parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument
  3. parrot(110, voltage=220) # duplicate value for the same argument
  4. parrot(actor='John Cleese') # unknown keyword argument

在函数调用中,关键字参数必须跟随在位置参数的后面。传递的所有关键字参数必须与函数接受的其中一个参数匹配(比如 actor 不是函数 parrot 的有效参数),它们的顺序并不重要。这也包括非可选参数,(比如 parrot(voltage=1000) 也是有效的)。不能对同一个参数多次赋值。下面是一个因为此限制而失败的例子:

  1. >>> def function(a):
  2. ... pass
  3. ...
  4. >>> function(0, a=0)
  5. Traceback (most recent call last):
  6. File "<stdin>", line 1, in <module>
  7. TypeError: function() got multiple values for keyword argument 'a'

当存在一个形式为 name 的正式形参时,它会接收一个字典 (参见 映射类型 —- dict),其中包含除了与正式形参相对应的关键字参数以外的所有关键字参数。 这可以与一个形式为 name,接收一个包含除了正式形参列表以外的位置参数的 元组 的正式形参 (将在下一小节介绍) 组合使用 (name 必须出现在 name 之前。) 例如,如果我们这样定义一个函数:

  1. def cheeseshop(kind, *arguments, **keywords):
  2. print("-- Do you have any", kind, "?")
  3. print("-- I'm sorry, we're all out of", kind)
  4. for arg in arguments:
  5. print(arg)
  6. print("-" * 40)
  7. for kw in keywords:
  8. print(kw, ":", keywords[kw])

它可以像这样调用:

  1. cheeseshop("Limburger", "It's very runny, sir.",
  2. "It's really very, VERY runny, sir.",
  3. shopkeeper="Michael Palin",
  4. client="John Cleese",
  5. sketch="Cheese Shop Sketch")

当然它会打印:

  1. -- Do you have any Limburger ?
  2. -- I'm sorry, we're all out of Limburger
  3. It's very runny, sir.
  4. It's really very, VERY runny, sir.
  5. ----------------------------------------
  6. shopkeeper : Michael Palin
  7. client : John Cleese
  8. sketch : Cheese Shop Sketch

注意打印时关键字参数的顺序保证与调用函数时提供它们的顺序是相匹配的。