Python中函数参数的传递方式分为:
(1)位置参数
这个说白一点就是普通的参数传递,比如定义一个求和函数:
def fun1(a,b):
return a+b
其中的参数a和b即为位置参数
(2)默认参数
有时候需要给参数设定一个默认值,比如定义一个求次方的函数:
def fun2(x,n=2)
return x**n
其中 n=2即为默认参数,调用的方式如下:
● fun2(5,4):计算5的4次方
● fun2(5): 计算5的平方
(3)可变参数
顾名思义,即可以传入任意个数的参数(包括0个),比如定义一个求和函数:
def fun3(*x):
calc=1
for a in x:
calc+=a
return calc
该函数与上面位置参数的不同之处在于:可以传入任意个参数参与计算,也可直接传入一个list或者tuple,而位置参数那里只能传两个,调用方式如下:
● fun3(1, 2, 3, 4, 5):计算1-5的和
● L = [1, 2, 3, 4, 5] fun3(*L):计算1-5的和
(4)关键字参数
关键字参数允许传入任意个含参数名的参数(包括0个),比如定义一个学生信息录入函数:
def fun4(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
调用方式如下:
● 只传入必选参数,如:fun4('zhou',21);
● 传入任意个数的关键字参数,如:person('zhou',21city='sq',job='stu');
● 先组装出一个dict,然后,把该dict转换为关键字参数传进去,如:
a={'city':'sq','job':'stu'};fun4('zhou',21,**a)
(5)命名关键字参数
即限制了关键字参数的名字,大白话就是可以传入关键字参数,但是不能瞎取名字,得按给定的名字来。
格式:fun(a,*,b),命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
def fun5(name,age,*,city,job):
print(name,age,city,job)
调用方式如下:
● fun5('zhou',21,city='sq',job='stu')
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:即fun5(a,*b,c)
参数的调用顺序:
位置参数>默认参数>可变参数>关键字参数>命名关键字参数
def f(a,b,c=0,*d,**kw):
print('a=',a,'b=',b,'c=',c,'d=',d,'kw=',kw)
解惑:
①普通的位置参数也可以传入list或者tuple,比如fun1的调用:
● print(fun1([1,2,3],[4,5,6]))
● print(fun1((1,2,3),(4,5,6)))
②默认参数的坑:
def add_fun(a=[]):
a.append('END')
return a
此函数调用时,会出现如下结果:
>>>add_fun()
['END','END']
>>>add_fun()
['END','END', 'END']
解决默认参数的坑:定义默认参数要牢记一点:默认参数必须指向不变对象。None是不变对象,上述代码可改为:
def add_fun(a=None):
if(a is None):
a=[]
a.append('END')
return a
关于原数据经过函数作用后是否改变的问题:
(1)普通的修改不会改变原数据的值,例如:
defswap(a,b)
a,b=b,a
return a,b
调用①,a=3;b=4 print(swap(a,b)),调用结束后a和b的值不会发生改变;
调用②,a=[1,2,3];b=[4,5,6] print(swap(a,b)),调用结束后a和b的值不会改变。
(2)会改变的情况:
对于列表,在函数中修改元素列表(如a[0]=6)、添加元素(如a.append(4))、删除元素(如a.pop()/a.remove(1))都会使得原列表发生改变,如下表所示:
| | | print('调用后b=',b) | print('调用后b=',b) |
结果 | a= [6, 2, 3] b= [4, 5, 6] | a= [1, 2, 3, 4] b= [4, 5, 6] | a= [1, 2] b= [4, 5, 6] | a= [2, 3] b= [4, 5, 6] |
(3)禁止函数修改列表:
向函数传递列表的副本而不是原件,这样在函数中所做的修改不会影响到原列表,如下所示:
function_a(list_a[:])
切片表示法创建列表的副本。