Python可变长度的函数参数
在编程的过程中,我们可能会遇到函数参数个数不固定的情况。这时就需要使用可变长度的函数参数来实现我们的功能。在Python中,有两种变长参数,分别是元组(非关键字参数)和字典(关键字参数)。其调用方式是:func( *tuple_grp_nonkw_args, **dict_grp_kw_args )
,下面将详细介绍这两种变长参数。
1.元组变长参数
当函数调用中包括一个元组变长参数*tuple_grp_nonkw_args时,除去前面固定位置参数和关键字参数的其余参数将按顺序插入一个元组进行访问,这和C语言中的varargs的功能相同。
假设有这样一个函数(其中,positional_arg是位置固定的标准调用参数,keyword_arg是关键字参数):
1 2 3 4 5 |
def foo( positional_arg, keyword_arg='default', *tuple_arg ): print "positional arg: ", positional_arg print "keyword_arg: ", keyword_arg for each_additional_arg in tuple_arg: print "additional_arg: ", each_additional_arg |
我们使用一些示例来了解它是怎么工作的:
1 2 3 4 5 6 7 8 9 10 11 12 |
>>> foo(1) positional arg: 1 keyword_arg: default >>> foo(1, 2) positional arg: 1 keyword_arg: 2 >>> foo(1, 2, 3) positional arg: 1 keyword_arg: 2 additional_arg: 3 |
2.字典变长参数
既然Python中允许关键字参数,那么也应该有一种方式实现关键字的变长参数,这就是字典变长参数。
字典变长参数中,额外的关键字参数被放入了一个字典进行使用。字典中,键为参数名,值为相应的参数值。其表示方式是放在函数参数最后的**开头的参数,如**dict_grp_kw_args。(需要注意的是,**被重载以不与幂运算混淆。)
以下是一个字典变长参数的示例函数:
1 2 3 4 5 |
def foo( positional_arg, keyword_arg='default', **dict_arg ): print "positional arg: ", positional_arg print "keyword_arg: ", keyword_arg for each_dict_arg in dict_arg.keys(): print "dict_arg: %s=>%s" % ( each_dict_arg, str( dict_arg[each_dict_arg] ) ) |
下面是一段演示结果:
1 2 3 4 |
>>> foo(1, 2, a="b") positional arg: 1 keyword_arg: 2 dict_arg: a=>b |
3.注意
函数调用的完整表达形式为:
func( positional_args, keyword_args, *tuple_grp_nonkw_args, **dict_grp_kw_args )
在使用的过程中,所有参数都是可选的,但应当注意的是:上面四种参数的位置是不可调换的!
4.扩展:C语言中的变长参数
作为一个学艺不精的人,之前一直不知道C语言中也是有可变参数的,直到在《Pointers on C》(中译名:《C和指针》,人民邮电出版社)中看到相关内容(7.6节)。
4.1 stdarg宏
在C语言中,可变参数是通过stdarg宏来实现的,它是标准库的一部分。这个头文件声明了一个类型va_list
和三个宏va_start
、va_arg
、va_end
。我们可以声明一个类型为va_list的变量,与三个宏配合使用,访问参数的值。
下面是一个计算多个数值平均值的示例函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <stdarg.h> float avg( int n, ... ) { va_list var_arg; float sum = 0; // 准备访问变长参数 va_start( var_arg, n ); // 添加取自变长参数列表的值 for ( i = 0; i < n; i += 1) { sum += va_arg( var_arg, int ); } // 完成处理变长参数 va_end( var_arg); return sum / n; } |
其中,函数参数中的...
作为参数占位符,代表数量和类型不可知的一些参数。
函数中声明了一个va_list类型的变量var_arg用于访问参数列表的不确定部分。这个变量通过调用va_start进行初始化,其中,第一个参数是va_list变量的名字,第二个参数是占位符前最后一个有名字的参数。初始化过程将var_arg变量指向可变参数中的第一个参数。
va_list的使用中,包括两个参数,第一个参数是va_list变量,第二个参数是下一个参数的类型。本例中假设输入数据均为整型,因此均设置为int,而在一些情况下,下一个参数的类型会由之前的参数来决定。
最后,调用va_end结束变长参数的访问。
4.2 限制与注意事项
可变参数是从头到尾进行访问的,即可以在访问了数个参数之后结束,但不可以一开始就访问中间的参数。
另外,由于可变参数部分没有原型,因此作为可变参数传递给函数的值都做了缺省的函数类型提升。
从va_start的调用可以看出,如果使用可变参数必须有至少一个确定的参数,否则无法使用va_start。
对于这些宏,有两个基本限制:其一,无法判断实际存在的参数数量;其二,不能判断参数类型。
还需要注意的是,一旦在使用中写错下一个参数的类型,后果可能不堪设想。
本文内容遵从CC3.0版权协议,转载请注明:转自Pythoner
本文链接地址:Python可变长度的函数参数
暂无评论