函数的参数类型可分为:必选参数、默认参数、可变参数(不定长参数)、关键字参数、组合参数,总共5种。
def my_func1(x1, *x2, x3, x5 = 4, x4 = 1 ):
函数定义时的参数称为: 形参。
函数调用时给的参数称为: 实参。
默认参数: 带有默认的参数值,调用时可以不用给出实参。
值得注意的是,我们在定义函数时形参数量只有一个,因此在调用函数时传入实参也必须是一个!如果传入的实参数量多余形参数量会出现错误,
【改变默认参数的值】
def my_func2(x2, x3=4):
return x2, x3
print('不对默认参数给实参:', my_func2(2))
print('改变默认参数: ', my_func2(2,1))
结果为:
不对默认参数给实参: (2, 4)
改变默认参数: (2, 1)
重点来了:当存在默认参数和必须参数两种以上参数时,调用函数时一定要注意:
a : 调用函数时,默认实参的形式为都带参数名,如上图形式
# 函数定义时 默认参数推荐在后
def my_func3(x1, x2, x3=4):
return x1, x2, x3
print('不对默认参数给实参:', my_func3(2, 1))
print('对默认参数给实参,实参加参数名: ', my_func3(2, 1, x3 = 5))
结果为:
不对默认参数给实参: (2, 1, 4)
对默认参数给实参,实参加参数名: (2, 1, 5)
【形参中默认参数在后,实参中默认参数在后】
形参中默认参数在前,实参中默认参数在后导致报错:
def my_func3(x1, x2, x3=4):
return x1, x2, x3
print('对默认参数给实参,实参加参数名,改变默认参数位置: ', my_func3(2, x3 = 5, 5))
c : 如果形参中默认参数在必须参数之前,那么调用函数时实参中默认参数也应当在前面;如果形参中默认参数在必须参 数之后,那么调用函数时实参中默认函数应当在后面,否则会报错。
#在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
#我们以数学题为例子,给定一组数字 a , b , c … … a,b,c…… a,b,c…… ,请计算 a 2 + b 2 + c 2 + … … a^2 + b^2 + c^2 + …… a2+b2+c2+……。
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
但是调用的时候,需要先组装出一个list或tuple:
print(calc( (1,2,3) ))
改进使用可变参数:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
如果利用可变参数,调用函数的方式可以简化成这样:
print(calc(1,2,3))
定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数。
可变参数的理解:
def change(age,*som):
print('第一个实参 age = ', age)
print('第二个实参 *som = ', *som)
return age, *som
print(change(1, 2, 5, 5, 9))
结果为:
第一个实参 age = 1
第二个实参 *som = 2 5 5 9
(1, 2, 5, 5, 9)
我们可以看到,在形参中我们定义了两个参数,为什么实参中输入了4个参数还是正确的呢?
这就是可变参数带来的好处!代码中实参 1 传给了形参age,而其余三个传给了*som,可以说som相当于一个无限大的容器,可以容纳很多个参数。
注意:一般使用 *args
作为通用的可变参数名
其实默认参数中已经出现了关键字参数!**关键字参数就是在调用函数时,传入实参时带参数名,用这样的方式传入的实参叫做关键字参数。**在这里,我们重点讲一下调用函数时传入关键字参数的几种方法。
**kw 参数,以字典的形式传入参数
dir={'grade': 12, 'job':'student'}
def Deaf(name, age, **kw):
print('姓名: ', name, '年龄: ', age, '其他信息:', kw)
print(Deaf('haowei', 18, **dir))
结果为:
姓名: haowei 年龄: 18 其他信息: {'grade': 12, 'job': 'student'}
注意: 必须以 ** + 字典名的形式传入,否则报错
dir={'grade': 12, 'job':'student'}
def Deaf(name, age, *arg):
print('姓名: ', name, '年龄: ', age, '其他信息:',arg)
print('test1-----> ',Deaf('haowei', 18, dir))
print('test1-----> ',Deaf('haowei', 18, *dir))
姓名: haowei 年龄: 18 其他信息: ({'grade': 12, 'job': 'student'},)
test1-----> None
姓名: haowei 年龄: 18 其他信息: ('grade', 'job')
test1-----> None
(1)形参有不定长参数 *arg,调用函数时用 dir 但其结果是 将字典以元组的形式输出,既在字典外面加括号。
(2)当形参中有不定长参数 *arg,调用函数时用 *dir会发现结果是只有字典中键名,没有值!
组合参数就是将之前讲过的4中参数同时引入函数作为形参,值得注意的是,定义参数时的顺序必须为:必须参数、关键字参数、默认参数、不定长参数。
def func(a, b, c=0, *args, **kw):
print ('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,运行会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个 tuple;
**kw是关键字参数,kw接收的是一个 dict 。
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({‘a’: 1, ‘b’: 2})。
使用*args和kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。**