我们知道,对于变长的函数参数,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)
"""
|