最近在带着新成员一起学习《Python基础教程》这本书,看到参数魔法的时候
突然感觉好多术语真的不知道呀~
Python参数:位置参数,关键字参数
经常看Python我们肯定经常看见,下面类似这样的代码
def add(x,y):
return x+y
# 1
add(1,2)
# 2
add(x=1,y=2)
上面的两段代码结果是一样,但是含义却不一样
第一种叫做位置参数:即,add函数根据调用时参数传进来时候的位置来确定谁是x,谁是y
第二种叫做关键字参数:即,add函数根据调用时指定的参数对应值来确定x,y;这时也可以写成add(y=2,x=1)
两种方法各有自己的用途
Python收集参数
我们都应该知道在Python3(2不支持)在解压可迭代对象是有星号表达式
进行多个元素的不确定解包
然后收集参数是什么呢?如名字所示,就是当参数个数不定时,我们函数的定义,类似收集的方式,满足不定长参数需求
这里就也用到了星号*,不过星号表达式在解压可迭代对象时生成的是个列表,收集参数则要看星号的数量来决定类型
下段代码运行所示:
_, *b, _ = ["hello", "world", "test", "ddd"]
print(b)
def test(*parameter1, **parameter2):
print('parameter1=', parameter1)
print('parameter2=', parameter2)
test("hello", "world", fo="a", ss="b")
如图片所示,
收集参数中使用一个星号,即“*”,会对调用时导入的位置参数进行‘收集’转为元祖
收集参数中使用两个星号,即“**”,会对调用时导入的关键字参数进行“收集”转换为字典
此时你可能已经联想到了经常遇到的 args,*kwargs,后面会提到
“收集参数“反转
上面提到了收集参数,针对函数定义在参数位置利用*来进行不定参数的收集
同时,我们也可以利用类似的‘逆运算’,进行代码编写
如下面代码:
test1 = ("hello", "world")
def test(parameter1, parameter2):
print("1.", parameter1,)
print("2.", parameter2)
test(*test1)
args,*kwargs
如上面收集参数所示,在Python中只是习惯默认定义args为位置参数收集参数
*kwargs为关键字参数收集参数
他们之间的区别也如上所示,我们什么时候会用到他们呢?
子类化
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2
class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)
装饰器
def mydecorator( f ):
@functools.wraps( f )
def wrapper( *args, **kwargs ):
print "Calling f", args, kwargs
v = f( *args, **kwargs )
print "f returned", v
return v
return wrapper
PS:
注意收集参数顺序,位置参数必须在关键字参数之前
也就是说,args和**kwargs同时出现时,args必须位于前面