我们知道,对于变长的函数参数,php中可以用数组,js中可以使用对象来进行传参。
而收集函数参数,php中使用的方法为func_get_args(),在js中则使用arguments属性来获取(此属性类似数组)
在python中,我们如何获取变长参数呢
第一:使用列表,字典,元组
例如
def demo(x): for s in x: print (s) |
此处注意,元组具有不可变性,所以,在函数内不应该修改元组,否则会报错,如下
def demo(x): x[ 0 ] =
1 demo(( 1 , 2 , 3 , 4 )) """ 上述会输出如下错误信息 Traceback (most recent call last): .... TypeError: 'tuple' object does not support item assignment """ |
第二:使用可变参数
def demo( * args, * * kargs): print (args) print (kargs) demo() """ () {} """ demo( 1 , 2 ) """ (1,2) {} """ demo(c = 'a' ,b = 'd' ) """ () {'c': 'a', 'b': 'd'} """ demo( 1 , 2 ,c = 'a' ,b = 'd' ) """ (1, 2) {'c': 'a', 'b': 'd'} """ |
其中,*args将收集所有位置相关的参数,并放到一个元组中,最后将这个元组赋值给args
而**kargs指针对关键字参数(指a=3这一类型),这些关键字参数会放到一个相应的字典中,然后同样的赋值给kargs
与此相对,python中还有解包参数。参考以下程序
def demo(a,b,c): print (a,b,c) |
正常调用的情况下,我们得传三个参数,例如demo(1,2,3)
但有了解包参数,我们可以只用传一个元组就可以实现
def demo(a,b,c): print (a,b,c) arg = ( 1 , 2 , 3 ) demo(arg) """ Traceback (most recent call last): ... TypeError: demo() takes exactly 3 arguments (1 given) """ demo( * arg) """ (1, 2, 3) """ |
*arg可以解包元组,而**arg则可以解包字典
参考以下程序
def demo(a,b,c): print (a,b,c) arg = { 'a' : 4 , 'b' : 5 , 'c' : 6 } demo( * * arg) #(4, 5, 6) |
注意收集参数和参数解包形式上很相似,要注意区别。
收集函数是,在形参中,利用*,**来实现
参数解包,则是在实参中,利用*,**来实现
有了以上基础,我们来模拟map()的实现
def mymap(func, * seqs): res = [] for args in zip ( * seqs): res.append(func( * args)) return res print (mymap( abs ,[ - 2 , - 1 , 0 , 1 , 2 ])) """ 收集参数构成seqs成员元祖([-2,-1,0,1,2],) 通过*seqs解包传入zip,得到元祖 (-2,),(-1,),(0,),(1,),(2,) 循环遍历之后,通过解包参数为 abs(-2),abs(-1),abs(0),abs(1),abs(2) """ print (mymap( pow ,[ 1 , 2 , 3 ],[ 2 , 3 , 4 , 5 ])) """ zip()通过*seqs解包参数得到三个元祖 (1,2),(2,3),(3,4) 遍历循环之后,元祖解包成为pow的两个参数于是 pow(1,2),pow(2,3),pow(3,4) """ |