一.参数分类
1.形式参数(形参)
什么是形式参数
函数在'定义阶段'括号中定义的'变量名'就是形式参数,简称'形参'
def index(a, b):
pass
# a,b 就是形参
2.实际参数(实参)
什么是实际参数
函数在'调用阶段'括号中写的'变量值'就是实际参数,简称'实参'
def index(a, b):
pass
index(1, 2)
# 1, 2就是函数的实参
二.形参与实参的使用
1.位置参数(重要)
什么是位置参数:位置参数指的是按顺序定义的参数
在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值
在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
2.关键字参数(重要)
什么是关键字参数:在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
需要注意在调用函数时,实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
3.默认参数(重要)
在定义函数时,就已经为形参赋值,这类形参称之为默认参数。
- 当函数有多个参数时,需要将值经常改变的参数定义为位置参数,而将值改变少的参数定义为默认函数
- 定义时就已经为参数赋值了,意味着调用时可以不对参数赋值,降低了函数调用难度
需要注意:
- 默认参数必需在位置参数之后
- 默认参数的值只能在函数定义阶段被赋值一次
- 默认参数的值一般设为不可变类型
4.可变长度的参数(重要)
如果在最后一个形参名前加号,那么在调用函数时,溢出的位置实参,都会被接收,以元组的形式保存下来赋值给该形参
>>> def foo(x,y,z=1,*args): #在最后一个形参名args前加*号
... print(x)
... print(y)
... print(z)
... print(args)
...
>>> foo(1,2,3,4,5,6,7) #实参1、2、3按位置为形参x、y、z赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args,即args=(4, 5, 6,7)
1
2
3
(4, 5, 6, 7)
如果我们事先生成了一个列表,仍然是可以传值给*args的
>>> def foo(x,y,*args):
... print(x)
... print(y)
... print(args)
...
>>> L=[3,4,5]
>>> foo(1,2,*L) # *L就相当于位置参数3,4,5, foo(1,2,*L)就等同于foo(1,2,3,4,5)
1
2
(3, 4, 5)
注意:如果在传入L时没有加*,那L就只是一个普通的位置参数了
>>> foo(1,2,L) #仅多出一个位置实参L
1
2
([1, 2, 3],)
如果形参为常规的参数(位置或默认),实参仍可以是*的形式
>>> def foo(x,y,z=3):
... print(x)
... print(y)
... print(z)
...
>>> foo(*[1,2]) #等同于foo(1,2)
1
2
3
如果我们想要求多个值的和,*args就派上用场了
>>> def add(*args):
... res=0
... for i in args:
... res+=i
... return res
...
>>> add(1,2,3,4,5)
15
5.可变长度关键字参数(*和**在形参和实参中使用)(重要)
如果在最后一个形参名前加号,那么在调用函数时,溢出的关键字参数,都会被接收,以字典的形式保存下来赋值给该形参
>>> def foo(x,**kwargs): #在最后一个参数kwargs前加**
... print(x)
... print(kwargs)
...
>>> foo(y=2,x=1,z=3) #溢出的关键字实参y=2,z=3都被**接收,以字典的形式保存下来,赋值给kwargs
1
{'z': 3, 'y': 2}
如果我们事先生成了一个字典,仍然是可以传值给**kwargs的
>>> def foo(x,y,**kwargs):
... print(x)
... print(y)
... print(kwargs)
...
>>> dic={'a':1,'b':2}
>>> foo(1,2,**dic) #**dic就相当于关键字参数a=1,b=2,foo(1,2,**dic)等同foo(1,2,a=1,b=2)
1
2
{'a': 1, 'b': 2}
注意:如果在传入dic时没有加**,那dic就只是一个普通的位置参数了
>>> foo(1,2,dic) #TypeError:函数foo只需要2个位置参数,但是传了3个
如果形参为常规参数(位置或默认),实参仍可以是**的形式
>>> def foo(x,y,z=3):
... print(x)
... print(y)
... print(z)
...
>>> foo(**{'x':1,'y':2}) #等同于foo(y=2,x=1)
1
2
3
如果我们要编写一个用户认证的函数,起初可能只基于用户名密码的验证就可以了,可以使用**kwargs为日后的扩展供良好的环境,同时保持了函数的简洁性。
>>> def auth(user,password,**kwargs):
... pass
...
6.命名关键字参数(了解)
命名关键字传参:在形参中会出现*的用法,如果出现在*号后面的形参,那么,实参传递的时候,必须以关键字的形式传递(在源代码中出现这种写法能看懂即可)
def register(name,age,*,sex,height,salary): #sex,height为命名关键字参数
pass
# register('kevin', 10, 'male', 1.9)
register('kevin', 10, sex='male', height=1.9, salary=2000)