跳转到主要内容
模块 5 · 第 3 课(共 4)课程中的19/36~12 min
模块课程(3/4)

*args 和 **kwargs

有时您需要一个接受 变量数 的函数 论据。 Python 为您提供了两个工具: *args (收集位置参数 到一个元组中)和 **kwargs (将关键字参数收集到一个字典中)。

*args:可变位置参数

Python
def somma_tutto(*nums):
    totale = 0
    for n in nums:
        totale += n
    return totale

somma_tutto(1, 2, 3)         # 6
somma_tutto(1, 2, 3, 4, 5)   # 15
somma_tutto()                # 0

在函数内部, nums 是一个包含所有传递值的 元组。的 名称只是一个约定: *args 是最常见的,但是 *nums 或 *valori 完全有效。

**kwargs:可变关键字参数

Python
def crea_config(**opzioni):
    return opzioni

crea_config(debug=True, port=8080)
# {'debug': True, 'port': 8080}

在函数内部,opzioni 是一个带有 {param_name: value} 的 dict。

结合一切

固定顺序为:**常规参数、*args、默认参数、**kwargs**。

Python
def f(primo, *args, opzione="x", **kwargs):
    print(primo, args, opzione, kwargs)

f(1, 2, 3, opzione="y", extra=10)
# 1 (2, 3) y {'extra': 10}

在调用中解包:* 和 **

相同的运算符以相反的方式工作:“分解”列表/元组 到位置参数或字典到关键字参数。

Python
def punto(x, y, z):
    return (x, y, z)

coords = [1, 2, 3]
punto(*coords)        # punto(1, 2, 3)  →  (1, 2, 3)

opts = {"x": 1, "y": 2, "z": 3}
punto(**opts)         # punto(x=1, y=2, z=3)

包装图案

Python
def log_chiamata(fn, *args, **kwargs):
    print(f"chiamo {fn.__name__} con {args=} {kwargs=}")
    return fn(*args, **kwargs)

log_chiamata(max, 3, 1, 2)             # calls max(3, 1, 2)
log_chiamata(sorted, [3, 1, 2], reverse=True)

函数签名中的参数排序

定义接受多个参数类型的函数时,必须遵守签名中的严格顺序:

  1. 标准位置参数。
  2. 位置可变参数 *args。3.具有默认值的关键字参数。
  3. 关键字可变参数 **kwargs。

尝试一下

锻炼#python.m5.l3.e1
尝试:0加载中...

定义返回算术平均值(总和/计数)的“average(*nums)”。用 10, 20, 30 调用它,并将结果赋给 `m`。评估“m”。

正在加载编辑器...
显示提示

总和(数字)/ 长度(数字)

3 次尝试后可用的解决方案

复习练习

锻炼#python.m5.l3.e2
尝试:0加载中...

给定函数“def point(x, y, z): return x + y + z”和字典“coords = {'x': 1, 'y': 2, 'z': 3}”,调用点解包坐标并将结果分配给“s”。评估“s”。

正在加载编辑器...
显示提示

点(**坐标)

3 次尝试后可用的解决方案

额外的挑战

锻炼#python.m5.l3.e3
尝试:0加载中...

Write a function `multiply_all(*args)` that returns the product of all numbers passed as arguments. If no arguments are passed, it should return `1`. Finally, evaluate the call `multiply_all(2, 3, 4)`.

正在加载编辑器...
显示提示

使用 for 循环迭代 args 中的元素并累加它们的乘积。

3 次尝试后可用的解决方案