首页 / 操作系统 / Linux / Python函数参数类型小结
刚开始学习Python,Python相对于java确实要简洁易用得多。内存回收类似hotspot的可达性分析, 不可变对象也如同java得Integer类型,with函数类似新版本C++的特性,总体来说理解起来比较轻松。只是函数部分参数的"*"与"**"等问题。着实令人迷糊了一把,弄清概念后写下此文记录下来,也希望本文能够帮助其他初学者。
不带“*”,"*" 与 "**"的区别
理解这个问题得关键在于要分开理解调用和声明语法中3者得区别.函数调用区别
不同类型的参数
#这里先说明python函数调用得语法为:func(positional_args, keyword_args, *tuple_grp_nonkw_args, **dict_grp_kw_args)#为了方便说明,之后用以下函数进行举例 def test(a,b,c,d,e): print a,b,c,d,e举个例子来说明这4种调用方式得区别:#-------------------------------#positional_args方式>>> test(1,2,3,4,5)1 2 3 4 5#这种调用方式的函数处理等价于a,b,c,d,e = 1,2,3,4,5print a,b,c,d,e#-------------------------------#keyword_args方式>>> test(a=1,b=3,c=4,d=2,e=1)1 3 4 2 1#这种处理方式得函数处理等价于a=1b=3c=4d=2e=1print a,b,c,d,e#-------------------------------#*tuple_grp_nonkw_args方式>>> x = 1,2,3,4,5>>> test(*x)1 2 3 4 5#这种方式函数处理等价于a,b,c,d,e = xprint a,b,c,d,e#特别说明:x也可以为dict类型,x为dick类型时将键传递给函数>>> y{"a": 1, "c": 6, "b": 2, "e": 1, "d": 1}>>> test(*y)a c b e d#---------------------------------#**dict_grp_kw_args方式>>> y{"a": 1, "c": 6, "b": 2, "e": 1, "d": 1}>>> test(**y)1 2 6 1 1#这种函数处理方式等价于a = y["a"]b = y["b"]... #c,d,e不再赘述print a,b,c,d,e不同类型参数混用
接下来说明不同参数类型混用的情况,要理解不同参数混用得语法需要理解以下几方面内容.首先要明白,函数调用使用参数类型必须严格按照顺序,不能随意调换顺序,否则会报错. 如 (a=1,2,3,4,5)会引发错误,; (*x,2,3)也会被当成非法.其次,函数对不同方式处理的顺序也是按照上述的类型顺序.因为#keyword_args方式和**dict_grp_kw_args方式对参数一一指定,所以无所谓顺序.所以只需要考虑顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的顺序.因此,可以简单理解为**只有**#positional_args方式,#*tuple_grp_nonkw_args方式有罗辑先后顺序的.最后,参数是不允许多次赋值的.举个例子说明,顺序赋值(positional_args)和列表赋值(*tuple_grp_nonkw_args)的罗辑先后关系:#只有在顺序赋值,列表赋值在结果上存在罗辑先后关系#正确的例子1>>> x = {3,4,5}>>> test(1,2,*x)1 2 3 4 5#正确的例子2>>> test(1,e=2,*x)1 3 4 5 2#错误的例子>>> test(1,b=2,*x)Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: test() got multiple values for keyword argument "b"#正确的例子1,处理等价于a,b = 1,2 #顺序参数c,d,e = x #列表参数print a,b,c,d,e#正确的例子2,处理等价于a = 1 #顺序参数e = 2 #关键字参数b,c,d = x #列表参数#错误的例子,处理等价于a = 1 #顺序参数b = 2 #关键字参数b,c,d = x #列表参数#这里由于b多次赋值导致异常,可见只有顺序参数和列表参数存在罗辑先后关系函数声明区别
理解了函数调用中不同类型参数得区别之后,再来理解函数声明中不同参数得区别就简单很多了.函数声明中的参数类型说明
函数声明只有3种类型, arg, *arg, **arg 他们得作用和函数调用刚好相反. 调用时*tuple_grp_nonkw_args将列表转换为顺序参数,而声明中的*arg的作用是将顺序赋值(positional_args)转换为列表. 调用时**dict_grp_kw_args将字典转换为关键字参数,而声明中得**arg则反过来将关键字参数(keyword_args)转换为字典. *arg 和 **arg可以为空值. 以下举例说明上述规则:#arg, *arg和**arg作用举例def test2(a,*b,**c):print a,b,c#---------------------------#*arg 和 **arg可以不传递参数>>> test2(1)1 () {}#arg必须传递参数>>> test2()Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: test2() takes at least 1 argument (0 given)#----------------------------#*arg将顺positional_args转换为列表>>> test2(1,2,[1,2],{"a":1,"b":2})1 (2, [1, 2], {"a": 1, "b": 2}) {}#该处理等价于a = 1 #arg参数处理b = 2,[1,2],{"a":1,"b":2} #*arg参数处理c = dict() #**arg参数处理print a,b,c#-----------------------------#**arg将keyword_args转换为字典>>> test2(1,2,3,d={1:2,3:4}, c=12, b=1)1 (2, 3) {"c": 12, "b": 1, "d": {1: 2, 3: 4}}#该处理等价于a = 1 #arg参数处理b= 2,3 #*arg参数处理#**arg参数处理c = dict()c["d"] = {1:2, 3:4}c["c"] = 12c["b"] = 1print a,b,c处理顺序问题
函数总是先处理arg类型参数,再处理*arg和**arg类型的参数. 因为*arg和**arg针对的调用参数类型不同,所以不需要考虑他们得顺序. def test2(a,*b,**c):print a,b,c>>> test2(1, b=[1,2,3], c={1:2, 3:4},a=1)Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: test2() got multiple values for keyword argument "a"#这里会报错得原因是,总是先处理arg类型得参数#该函数调用等价于#处理arg类型参数:a = 1a = 1#多次赋值,导致异常#处理其他类型参数...print a,b,c--------------------------------------分割线 --------------------------------------CentOS上源码安装Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码] http://www.linuxidc.com/Linux/2013-11/92693.htmPython脚本获取Linux系统信息 http://www.linuxidc.com/Linux/2013-08/88531.htm在Ubuntu下用Python搭建桌面算法交易研究环境 http://www.linuxidc.com/Linux/2013-11/92534.htmPython 语言的发展简史 http://www.linuxidc.com/Linux/2014-09/107206.htmPython 的详细介绍:请点这里
Python 的下载地址:请点这里 本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-04/115828.htm