Python可变参数函数用法详解
来自:http://c.biancheng.net/view/2257.html
很多编程语言都允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数。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可变参数函数用法详解的更多相关文章
- Python中enumerate函数用法详解
enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等 一般情况下对一个列表或数组既要遍历索引又要遍历元素时, ...
- [转]使用python来操作redis用法详解
转自:使用python来操作redis用法详解 class CommRedisBase(): def __init__(self): REDIS_CONF = {} connection_pool = ...
- SQL中CONVERT()函数用法详解
SQL中CONVERT函数格式: CONVERT(data_type,expression[,style]) 参数说明: expression 是任何有效的 Microsoft® SQL Server ...
- php中setcookie函数用法详解(转)
php中setcookie函数用法详解: php手册中对setcookie函数讲解的不是很清楚,下面是我做的一些整理,欢迎提出意见. 语法: bool set ...
- eval()函数用法详解
eval()函数用法详解:此函数可能使用的频率并不是太高,但是在某些情况下具有很大的作用,下面就介绍一下eval()函数的用法.语法结构: eval(str) 此函数可以接受一个字符串str作为参数, ...
- 转载 LayoutInflater的inflate函数用法详解
http://www.open-open.com/lib/view/open1328837587484.html LayoutInflater的inflate函数用法详解 LayoutInflater ...
- C语言对文件的操作函数用法详解2
fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const ...
- C语言对文件的操作函数用法详解1
在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...
- 【Python】Python内置函数dir详解
1.命令介绍 最近学习并使用了一个python的内置函数dir,首先help一下: 复制代码代码如下: >>> help(dir)Help on built-in function ...
随机推荐
- css 对div用hover设置border,出现抖动和div走位问题,解决方法
样式设置 : div:hover { border:1px solid red;} 当鼠标移动到div时,产生抖动和偏移. 产生的原因: 是因为设置border时设置了1px边框,多出的这1px,与其 ...
- php压缩图片
<?php header('content-type:text/html;charset=utf8'); set_time_limit(0); $imgs=scandir('./Public/u ...
- PHP 多维数组将下标从0开始
点击链接加入群[php/web 学习课堂]:https://jq.qq.com/?_wv=1027&k=5645xiw 欢迎大家加入,一起讨论学习 模拟一个: public function ...
- 系统模块 sys 函数的调用
系统模块 sys 运行时系统相关的信息 sys模块的数据 数据 描述 sys.path 模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 '' sys.modules 已加载模块的字典 s ...
- Jenkins服务器安装与配置
Jenkins是一个非常出色的持续集成服务器,本文主要介绍在CentOS系统中Jenkins的基本安装配置方法,供参考. 一. 软件包: 1. 下载apache-maven-2.2.1-bin.tar ...
- 二十,基于K8S集群的PaaS简介
目录 一.概述 二.生产环境部署k8s,接下来我们描述一下在真正生产环境中我们部署k8s应该部署成什么样子 一.概述 1.通过以往的学习应该可以了解到k8s 和以往提到的devops概念更容易落地了. ...
- Educational Codeforces Round 40 C. Matrix Walk( 思维)
Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memor ...
- HDU 5876 补图最短路
开两个集合,一个存储当前顶点可以到达的点,另一个存储当前顶点不能到达的点.如果可以到达,那肯定由该顶点到达是最短的,如果不能,那就留着下一次再判. #include<bits/stdc++.h& ...
- a 标签的download 属性在谷歌浏览器下无法下载图片,如何处理?
a 标签的download属性在下载图片文件的时候是如何的方便,可是可是谷歌浏览器不支持下载,而是下载打开新窗口预览图片.这个兼容性问题如何解决呢? 了解了一番,HTMLCanvasElement.t ...
- 微信小程序 base64ToArrayBuffer
base64ToArrayBuffer 将 base64 的字符串转化为 ArrayBuffer 对象 示例代码: 使用位置:在 JS文件的任意函数中使用 const base64 = 'CxYh'; ...