定义仅限关键字参数

Python里的函数不光支持通过有序位置参数(positional argument)调用,还能指定参数名,通过关键字参数(keyword argument)的方式调用。

比如下面这个用户查询函数:

def query_users(limit, offset, min_followers_count, include_profile):
  """查询用户
  :param min_followers_count:最小关注者数量
  :param include_profile: 结果包含用户详细档案
  """
  ...

假如完全使用位置参数来调用它,会写出非常让人糊涂的代码:

# 时间长了, 谁能知道100和True分别代表什么呢?
query_users(20, 0, 100, True)

但如果使用关键字参数,代码会易读许多:

query_users(limit=20, offset=0, min_followers_count=100, include_profile=True)

# 关键字参数可以不严格按照函数定义参数的顺序来传递
query_users(min_followers_count=100, include_profile=True, limit=20, offset=0)

所以,当你要调用参数较多(超过3个)的函数时,使用关键字参数模式可以大大提高代码的可读性。虽然关键字参数调用模式很有用,但有一个美中不足之处:它只是调用函数时的一种可选方式,无法成为强制要求。不过,我们可以用一种特殊的参数定义语法来弥补这个不足:

# 注意参数列表中的*符号
def query_users(limit, offset, *, min_followers_count, include_profile):

通过在参数列表中插入*符号,该符号后的所有参数都变成了“仅限关键字参数”(keyword-only argument)。如果调用方仍然想用位置参数来提供这些参数值,程序就会抛出错误:

>>> query_users(20, 0, 100, True)
# 执行后报错:
TypeError:query_users() takes 2 positional arguments but 4 were given
# 正确的调用方式
>>> query_users(20, 0, min_followers_count=100, include_profile=True)

当函数参数较多时,通过这种方式把部分参数变为“仅限关键字参数”,可以强制调用方提供参数名,提升代码可读性。