python中函数的参数
形参:定义函数时代表函数的形式参数
实参:调用函数时传入的实际参数
列如:
def f(x,y): # x,y形参 print(x, y) f(1, 2) # 1, 2 实参
定义函数时,形参分为普通参数,默认参数,和动态参数
列如:
def f(x, y): # 普通参数 pass def f(x, y=1): # y=1是默认参数 pass def(x,y=1,*args): # *args普通动态参数 pass def(x,y=1,**kwargs): # **kwargs关键字动态参数 pass
调用函数时,根据调用时的写法,可以分为位置参数和关键字参数
def f(x,y): print('x=',x,'y'=,y) f(1,2) #我们这样调用的时候1,2叫位置参数,会根据传入的实参 #位置去对于形参的位置 输出结果为: x= 1 y= 2 f(x=1, y=2) f(y=2, x=1) #我们这样调用的时候,y=2,x=1叫做关键字参数 #可以不用按照位置写
那调用的时候同时写位置参数和关键字参数呢
还是以上面的f函数为例
f(x=1, 2) # 当我们吧关键字参数放前面 执行结果如下: File "F:/python/tt.py", line 9 f(x=1, 2) SyntaxError: non-keyword arg after keyword arg
得出结论:关键字参数不能放在位置参数前面,这个是语法规定
f(1, x=2) 执行结果: Traceback (most recent call last): File "F:/python/tt.py", line 9, in <module> f(1, x=2) TypeError: f() got multiple values for keyword argument 'x'
得出结论:如果位置参数和关键字参数需要同时匹配
那么根据这两条,我们还可以总结出定义函数时的规范:
1.默认参数要写在普通参数的后面
2.关键字动态参数**kwargs要写在最后面
我们再来看看动态参数是怎么运行的:
普通动态参数:
def f(x, *args): print(args) f(1, 2, '3', [1, 2, 3]) f(3, 2, [1, 2, 3]) 运行结果: (2, '3', [1, 2, 3]) (2, [1, 2, 3])
普通动态参数会将传入的所有多余的位置参数组合成一个元祖
关键字动态参数:
def f(x, y=1, **kwargs): print(kwargs) f(1, 2, z=2, a=3, d=4) f(3, 2, xx=2, name='xinlan', age=18) 运行结果: {'a': 3, 'z': 2, 'd': 4} {'age': 18, 'xx': 2, 'name': 'xinlan'}
关键字动态参数会将传入的多余的关键字参数组合成一个字典
案例:
d = { 'name': 'xinlan', 'age': 18 } def f(**kwargs): print(kwargs) f(**d) f(name='xinlan', age=18) 运行结果: {'name': 'xinlan', 'age': 18} {'name': 'xinlan', 'age': 18}
结论:将一个字典前加上**传入一个函数,相当于将这个字典中的键值对以关键字参数的形式传入函数。
案例:
l = ['python', 'php', 'java'] def f(*args): print(args) f(*l) f('python', 'php', 'java') 运行结果: ('python', 'php', 'java') ('python', 'php', 'java')
结论:将一个列表前加上*传入一个函数,相当于将这个列表中的元素按顺序传入函数
默认参数
默认参数的作用就是,如果我们在调用函数的时候不传入相应的参数,那么函数就用默认值
在定义函数的时候我们容易出现一个错误,看下面的例子:
def f(y=[]): y.append('ok') print(y) f() f() 执行结果: ['ok'] ['ok', 'ok']
我们调用了两次f函数,发现输出的结果不一样。这是因为列表,字典等这样的数据类型在调用的时候是引用它们的地址。
解释器在执行y=[]的时候,y指向的一个列表的引用地址,这个列表发生变化后,y指向的地址是没有变的
所以我们在定义函数的时候,默认参数不要定义成列表,字典等数据类型。当然我们有解决办法:
def f(y=None): # 这里None是一个占位符 if not y: y = [] y.append('ok') print(y) f() f() 执行结果 ['ok'] ['ok']