Python入门教程第59篇 函数进阶之可变参数

Posted 不剪发的Tony老师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python入门教程第59篇 函数进阶之可变参数相关的知识,希望对你有一定的参考价值。

本篇我们学习如何使用 *args 参数定义可变函数(variadic function)。

元组解包

以下示例将一个元组解包成两个变量:

x, y = 10, 20

元素 10 被赋予变量 x,元素 20 被赋予变量 y。

实际上,函数的传参也是类似:

def add(x, y):
    return x + y


add(10, 20)

以上示例中,元素 10 被传递给变量 x,元素 20 被传递给变量 y。

同样,以下示例将元素 10 赋予变量 x,元素 20 赋予变量 y,列表 [30, 40] 赋予变量 z:

x, y, *z = 10, 20, 30, 40

print(x)
print(y)
print(z)

Python 函数传参也执行相同的概念,例如:

def add(x, y, *args):
    total = x + y
    for arg in args:
        total += arg

    return total


result = add(10, 20, 30, 40)
print(result)

函数 add 接受三个参数:x、y 以及 *args。其中 args 是一个以星号开始的特殊参数。

当我们传递位置参数 10、20、30 以及 40 时,Python 将元素 10 赋予 x,20 赋予 y,元组 (30, 40) 赋予 args。函数传参和元组解包类似,只是 args 是一个元组,而不是列表。

可变参数

当函数的某个参数前面存在一个星号(*)时,表示它可以接收数量可变的参数值。用户可以给 *args 参数传递零个、一个或者多个值。

在 Python 中,类似 *args 的参数被称为可变参数(variadic parameter)。包含可变参数的函数被称为可变函数(variadic function)。

可变参数的名称不一定是 args。我们可以使用更加明确的参数名,例如 *numbers、*strings、*lists 等。按照惯例,一般使用 *args 作为可变参数的名称。

以下是一个示例:

def add(*args):
    print(args)


add()

输出结果如下:

()

add 函数打印了一个空元组。

以下示例显示了 args 参数的类型和内容:

def add(*args):
    print(type(args))
    print(args)

add()

输出结果如下:

<class 'tuple'>
()

由于我们没有传递任何参数, add() 函数输出了一个空元组。

接下来的示例为 add() 函数传递了三个参数值:

def add(*args):
    print(args)


add(1,2,3)

输出结果如下:

(1, 2, 3)

此时, args 参数包含了三个数字。我们可以使用下标访问每个元素:

def add(*args):
    print(args[0])
    print(args[1])
    print(args[2])


add(1, 2, 3)

另外,我们也可以使用 for 循环遍历 args 元组中的元素。以下示例演示了如何将元组中的元素进行求和:

def add(*args):
    total = 0
    for arg in args:
        total += arg
    return total


total = add(1, 2, 3)
print(total)

输出结果如下:

6

可变参数与位置参数

如果使用了 *args 参数,不能再指定其他的位置参数。不过,可以继续使用关键字参数。

以下示例返回了错误,因为它在 *arg 参数之后使用了位置参数:

def add(x, y, *args, z):
    return x + y + sum(args) + z


add(10, 20, 30, 40, 50)

错误信息如下:

TypeError: add() missing 1 required keyword-only argument: 'z'

为了解决这个问题,我们需要使用关键字参数调用函数:

def add(x, y, *args, z):
    return x + y + sum(args) + z


add(10, 20, 30, 40, z=50)

以上示例中,数字 10 被赋值给 x,20 被赋值给 y,(30,40) 被赋值给 args,最后 50 被赋值给 z。

参数解包

下面的 point 函数接收两个参数,返回一个字符串形式的坐标点:

def point(x, y):
    return f'(x,y)'

如果我们将一个元组作为参数传递给 point 函数,将会返回错误:

a = (0, 0)
origin = point(a)
TypeError: point() missing 1 required positional argument: 'y'

因为元组 a 作为一个完整的对象传递给 x,不会解包成两个元素分别传递给 x 和 y。所以参数 y 缺少数据。

为了解决这个问题,我们需要在实际参数前面加上 * 运算符,例如:

def point(x, y):
    return f'(x,y)'


a = (0, 0)
origin = point(*a)
print(origin)

输出结果如下:

(0,0)

此时,函数会将元组 a 进行解包并将两个元素分别赋值给 x 和 y。

总结

  • Python 使用 *arg 参数为函数指定可变数量的参数,也就是创建可变函数。
  • *args 可变参数之后只能使用关键字参数,不能使用位置参数。

以上是关于Python入门教程第59篇 函数进阶之可变参数的主要内容,如果未能解决你的问题,请参考以下文章

Python入门教程第61篇 函数进阶之偏函数

Python入门教程第62篇 函数进阶之类型提示

Python入门教程第58篇 函数进阶之元组解包

Python进阶第四篇函数

函数栈帧与可变参数列表 p1可变参数列表(完结)( C语言从入门到入土(进阶篇)

python进阶第1篇 函数入门