9、函数的参数
位置参数
def func(name, age, gender): print(name, age, gender)
name,age和gender都是函数func的位置参数,位置参数必须被传值,否则会报错
关键字参数
关键字参数指实参,实参以key=value的形式向形参传值
def func(name, age, gender): print(name, age, gender) # 关键字参数说的是实参传值给形参的方式 func(name='zh', age=18, gender='男')
默认参数
def func(name, gender, age=18): print(name, age, gender)
需要注意:默认参数必须在位置参数之后
默认参数的值在函数定义阶段被赋值一次
x = 1 def foo(arg=x): print(arg) x = 5 foo() # 1
默认参数的值应该是不可变类型,如果设置成可变类型,可能会出现下面这种问题
按照理解,每一次的L都应该只有111,但是,随着函数一直被调用,L中的元素不断变多,因为L在初始化时指向一个不可变对象,这个对象的值被改变,但是不会改变它的内存地址,导致L的内存地址一致没有改变,所以元素会越来越多
def foo(L=[]): L.append('111') print(L) foo() # ['111'] foo() # ['111', '111'] foo() # ['111', '111', '111'] foo() # ['111', '111', '111', '111']
如果默认值是不可变类型,就不会有这个问题
def foo(n, arg=None): if arg is None: arg = [] arg.append(n) return arg print(foo(1)) # [1] print(foo(2)) # [2] print(foo(3)) # [3]
可变长度的默认参数
如果在最后一个形参名前加上一个*,那么在调用函数时,溢出的位置实参,都会被接收,以元组的形式保存下来赋值给这个形参
def foo(x, y, z=1, *args): print(x) print(y) print(z) print(args) foo(1, 2, 3, 4, 5, 6) # 1 # 2 # 3 # (4, 5, 6)
如果事先产生了一个列表,也可以传入函数
def foo(x, y, z=1, *args): print(x) print(y) print(z) print(args) L = [223, 434, 666] foo(1, 2, 3, *L) # 1 # 2 # 3 # (223, 434, 666)
PS:*在实参的时候作用是打散,在形参的作用是聚合
可变长度的关键字参数
如果在最后一个形参名前加**号,那么在调用函数时,溢出的关键字参数都会被接收
def foo(x, **kwargs): print(x) print(kwargs) foo(1, y=2, z=3) # 1 # {'y': 2, 'z': 3}
同样可以用**来打散一个字典
def foo(x, **kwargs): print(x) print(kwargs) dic = {'a': 1, 'b': 2} foo(1, **dic) # 1 # {'a': 1, 'b': 2}
命名关键字参数
如果想要限定调用者必须以key=value的形式传递参数Python3提供了专门的语法:需要在定义形参时,用作为一个分隔符号,号之后的形参称为命名关键字参数。对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值
def foo(name, age, *, height, sex): pass foo('lili', 18, height=1.7, sex='male')
命名关键字参数也可以有默认值
如果形参中已经有了可变长度的关键字参数,那么命名关键字参数不需要加上*分隔符
def foo(name, age, *args, height, sex): pass
组合使用
所有参数可任意组合使用,但定义顺序必须是:位置参数、默认参数、args、命名关键字参数、*kwargs
可变参数*args与关键字参数kwargs通常是组合在一起使用的,如果一个函数的形参为*args与kwargs,那么代表该函数可以接收任何形式、任意长度的参数
def foo(*args, **kwargs): pass
浙公网安备 33010602011771号