函数的参数
一、形参和实参的定义
- 形参(形式参数,简称形参)
形参是函数在定义阶段就规定的参数,相当于定义变量的变量名,用来接收外部传来的值
- 实参(实际参数,简称实参)
实参是函数在调用阶段传入的参数,相当于定义变量的变量值,值可以是常量、变量、表达式或三者的组合
def index(a): #形参:相当于变量名
print(a)
a = 1
index(a) #实参:相当于变量值
在调用有惨函数时,实参(值)会赋值给形参(变量名)。在python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除
二、形参和实参的具体使用
位置就是顺序,指的是按顺序定义的参数
-
位置参数
- 在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参
def register(name, age, sex): # 定义位置形参:name,age,sex三者都必须被传值 print(f'Name:{name} Age:{age} Sex:{sex}') register() #TyperError:报错,缺少3个位置参数
- 在调用函数时,按照从左到右的顺序依次定义实参,成为位置实参
register('yang', 18, 'male') #对应关系为 name='yang', age=18,sex='male' Name:yang Age:18 Sex:male
-
关键字参数
在调用函数时,可以指定参数进行传参(key=value),成为关键字传参
register(name='yang', age=18, sex='male') #正确
register(name='yang', 18, sex='male') #报错:关键字参数name在位置参数18之前 register('yang', name='yang', age=18, sex='male') #报错:形参name被重复赋值
注意:位置参数和关键字参数连用的时候,位置参数一定一定要在关键字参数之前,而且不可以对用一个形参重复赋值
-
默认参数
在定义函数阶段时,就已经传入参数,这类形参称为默认参数,如果在实参的时候传入了一个新的参数,就会使用新参数
def register(name, age, sex='male'): #默认sex的值为male print(f'Name:{name} Age:{age} Sex:{sex}')
register('yang', 18) #大多数情况,无需为sex传值,默认为male Name:yang Age:18 Sex:male register('chen', 18, 'female') #少数情况,可以为sex传值femal Name:chen Age:18 Sex:female
默认参数在传值的时候,不要将可变类型当做参数传递
应用场景:
当参数对应值重复出现的情况下,使用默认参数
-
可变长参数(*与**的用法)
- *args:官方认证,也可以指定其他只要有 *的可变长参数
接收所有溢出的位置参数,接收的值都被存入一个元组
def foo(x, y, z=1, *args): #在最后一个形参名args前加个*号 print(x, y, z, 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, y, args) L = [3, 4, 5] foo(1, 2, L) 1 2 ([3, 4, 5])
实参中加个*号,可以打散传入的容器类型(需要放到实参中)
def foo(x, y, *args): print(x, y, *args) L = [3, 4, 5] foo(1, 2, *L) #相当于是foo(1,2,3,4,5) 1 2 3 4 5
例子:求多个值的和
def add(*args): res = 0 for i in args: res += i return res add(1, 2, 3, 4, 5) 15
- **kwargs:官方认证,也可以自定义指定
接收所有溢出的关键字参数,接收的值都被存入一个字典
def foo(x, **kwargs): #在最后一个参数kwargs前加** print(x, kwargs) foo(x=1, y=2, z=3) #溢出的关键字实参y=2,z=3会被**接收,以字典形式赋值给kwargs 1 {'y': 2, 'z': 3}
如果事先生成一个字典,也可以传值给**kwargs
def foo(x, y, **kwargs): print(x, y, 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: 函数只要两个位置参数,但是传了3个
如果形参为常规参数(位置或默认),实参仍然可以是**的形式
def foo(x, y, z=3): print(x, y, z) foo(**{'x':1, 'y':2}) #等同于foo(x=1,y=1) 1 2 3