Python可变参数函数用法详解

本文详细介绍了Python中可变参数函数的使用,包括逆向参数收集的概念。通过实例展示了如何将列表、元组、字典的元素传给函数参数,并解释了如何处理关键字参数和默认值。推荐学习目录:Python函数递归。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多编程语言都允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数。Python 当然也不例外,Python 允许在形参前面添加一个星号(*),这样就意味着该参数可接收多个参数值,多个参数值被当成元组传入。

 

下面程序定义了一个形参个数可变的函数:

  # 定义了支持参数收集的函数  def test(a, *books) :      print(books)      # books被当成元组处理      for b in books :          print(b)      # 输出整数变量a的值      print(a)  # 调用test()函数  test(5 , "C语言中文网" , "Python教程")

运行上面程序,将看到如下运行结果:

('C语言中文网', 'Python教程')
C语言中文网
Python教程
5

从上面的运行结果可以看出,当调用 test() 函数时,books 参数可以传入多个字符串作为参数值。从 test() 的函数体代码来看,参数收集的本质就是一个元组: Python 会将传给 books 参数的多个值收集成一个元组。

Python 允许个数可变的形参可以处于形参列表的任意位置(不要求是形参列表的最后一个参数),但 Python 要求一个函数最多只能带一个支持“普通”参数收集的形参。例如如下程序:

  # 定义了支持参数收集的函数  def test(*books ,num) :      print(books)      # books被当成元组处理      for b in books :          print(b)      print(num)  # 调用test()函数  test("C语言中文网", "Python教程", num = 20)

正如从上面程序中所看到的,test() 函数的第一个参数就是个数可变的形参,由于该参数可接收个数不等的参数值,因此如果需要给后面的参数传入参数值,则必须使用关键字参数,否则程序会把所传入的多个值都当成是传给 books 参数的。

Python 还可以收集关键字参数,此时 Python 会将这种关键字参数收集成字典。为了让 Python 能收集关键字参数,需要在参数前面添加两个星号。在这种情况下,一个函数可同时包含一个支持“普通”参数收集的参数和一个支持关键字参数收集的参数。例如如下代码:

  # 定义了支持参数收集的函数  def test(x, y, z=3, *books, **scores) :      print(x, y, z)      print(books)      print(scores)  test(1, 2, 3, "C语言中文网" , "Python教程", 语文=89, 数学=94)

上面程序在调用 test() 函数时,前面的 1、2、3 将会传给普通参数 x、y、z;接下来的两个字符串将会由 books 参数收集成元组;最后的两个关键字参数将会被收集成字典。运行上面代码,会看到如下输出结果:

1 2 3
('C语言中文网', 'Python教程')
{'语文': 89, '数学': 94}

对于以上面方式定义的 test() 函数,参数 z 的默认值几乎不能发挥作用。比如按如下方式调用 test() 函数:

test(1, 2, "C语言中文网" , "Python教程", 语文=89, 数学=94)

上面代码在调用 test() 函数时,前面的 1、2、"C语言中文网" 将会传递给普通参数 x、y、z;接下来的一个字符串将会由 books 参数收集成元组;最后的两个关键字参数将会被收集成字典。运行上面代码,会看到如下输出结果:

1 2 C语言中文网
('Python教程',)
{'语文': 89, '数学': 94}

如果希望让 z 参数的默认值发挥作用,则需要只传入两个位置参数。例如如下调用代码:

test(1, 2, 语文=89, 数学=94)

上面代码在调用 test() 函数时,前面的 1、2 将会传给普通参数 x、y,此时 z 参数将使用默认的参数值 3,books 参数将是一个空元组;接下来的两个关键字参数将会被收集成字典。运行上面代码,会看到如下输出结果:

1 2 3
()
{'语文': 89, '数学': 94}

逆向参数收集

所谓逆向参数收集,指的是在程序己有列表、元组、字典等对象的前提下,把它们的元素“拆开”后传给函数的参数。

逆向参数收集需要在传入的列表、元组参数之前添加一个星号,在字典参数之前添加两个星号。例如如下代码:

  def test(name, message):      print("用户是: ", name)      print("欢迎消息: ", message)  my_list = ['孙悟空', '欢迎来C语言中文网']  test(*my_list)

程序中定义了一个需要两个参数的函数,而 my_list 列表包含两个元素,为了让程序将 my_list 列表的两个元素传给 test() 函数,程序在传入的 my_list 参数之前添加了一个星号。

实际上,即使是支持收集的参数,如果程序需要将一个元组传给该参数,那么同样需要使用逆向收集。例如如下代码:

  def foo(name, *nums):      print("name参数: ", name)      print("nums参数: ", nums)  my_tuple = (1, 2, 3)  # 使用逆向收集,将my_tuple元组的元素传给nums参数  foo('fkit', *my_tuple)

上面程序中,调用将‘fkit’传给 foo() 函数的 name 参数,然后使用逆向收集将 my_tuple 包含的多个元素传给 nums 参数,nums 再将 my_tuple 的多个元素收集成元组。

运行上面代码,将看到如下输出结果:

name参数:  fkit
nums参数:  (1, 2, 3)

此外,也可使用如下方式调用 foo() 函数:

  # 使用逆向收集,将my_tuple元组的第一个元素传给name参数,剩下参数传给nums参数  foo(*my_tuple)

此时程序会对 my_tuple 进行逆向收集,其中第一个元素传给 name参数,后面剩下的元素传给 nums 参数。运行上面代码,将看到如下输出结果:

name参数:  1
nums参数:  (2, 3)

如果不使用逆向收集(不在元组参数之前添加星号),整个元组将会作为一个参数,而不是将元组的元素作为多个参数。例如按如下方式调用 foo() 函数:

  # 不使用逆向收集,my_tuple元组整体传给name参数  foo(my_tuple)

上面调用没有使用逆向收集,因此 my_tuple 整体作为参数值传给 name 参数。运行上面代码,将看到如下输出结果:

name参数:  (1, 2, 3)
nums参数:  ()

字典也支持逆向收集,字典将会以关键字参数的形式传入。例如如下代码:

  def bar(book, price, desc):      print(book, "VIP价格是:", price)      print('描述信息', desc)  my_dict = {'price': 159, 'book': 'C语言中文网', 'desc': '这是一个精美而实用的网站'}  # 按逆向收集的方式将my_dict的多个key-value传给bar()函数  bar(**my_dict)

上面程序中,bar() 需要三个参数。接下来程序定义了一个 my_dict 字典,该字典正好包含三个 key-value 对,程序使用逆向收集即可将 my_dict 包含的三个 key-value 对以关键字参数的形式传给 bar() 函数。

推荐学习目录:Python函数递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值