my_Info('Jock', '男', 25) # 仅给出必须参数
my_Info('Lucy', '女', 26, city='杭州') # 给出部分可选参数
my_Info('Kobe', '男', 41, '美国', '洛杉矶') # 给出全部可选参数
my_Info('Bob', '男', 71, nation='美国', city='洛杉矶') # 给出全部可选参数
结果输出:
我的名字是:Jock,性别:男,今年 25 岁,来自中国, 现居武汉
我的名字是:Lucy,性别:女,今年 26 岁,来自中国, 现居杭州
我的名字是:Kobe,性别:男,今年 41 岁,来自美国, 现居洛杉矶
我的名字是:Bob,性别:男,今年 71 岁,来自美国, 现居洛杉矶
在这个例子中,nation 和 city 就是默认参数,也可以称为可选参数。从这个例子我们可以发现,使用默认参数的好处在于:简化函数的调
用,降低函数调用的难度。调用函数的时候,默认参数可以不传,使用使用默认值,或者只传入部分默认参数,或者全部默认参数都
传。我们在使用 默认参数时要注意以下几点:
书写 和 调用 时位置参数(也称 必须参数(mandatory argument))在前,默认参数在后,否则 Python 解释器报错,大家可以思考一下这样设计
的好处是什么。后面还会给出例子。
函数有多个参数时,我们把变化大的参数放在前面,变化小的放在后面,变化小的参数可以设置为默认参数。
默认参数必须指向不可变对象。
Python 中 默认参数必须指向不可变对象 的原因是 默认参数的值有且仅在函数定义时计算 1 次,这是 Python 中非常容易踩坑的地方,我们看下面这例
子:
i = 5
def f(arg=i): # 定义函数时,arg 的默认值设为 5
print(arg)
i = 6
f()
输出结果:
5
如果我们把默认参数指向了不可变对象,会出现什么情况呢?看下面这个例子:
def f(a, L=[]):
L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
输出结果:
[1] [1, 2] [1, 2, 3]
我们发现输出结果并不是 [1]、[2]、[3] 。我们设置了 L 默认参数: L=[] ,可为什么 L 还会存储之前的调用结果呢?这是因为在 Python
中,默认参数值 在函数定义的时候就会被计算出来,并且默认值只会被计算一次,后面的函数调用都不会再对默认参数重新赋初值。这里
默认参数 L 在定义时,值被计算出来,即 [],因为参数 L 也是一个变量,指向了一个可变对象 [],每次调用该函数,如果改变了 L 指
向对象[]的值,则下次调用时,默认参数的内容就变了,不再是函数定义时的初值 []。
所以上面的例子我们改写如下:
def f(a, L=None):
if L is None:
L = [] L.append(a)
return L
print(f(1))
print(f(2))
print(f(3))
结果输出:
[1] [2] [3]
关键字参数关键字参数
关键字参数(keyword arguments) 是指调用函数时用 kwarg=value 的形式传入函数参数,其中 kwarg 就是 keyword arguments 的缩写。我们拿前
面位置参数的例子来展示关键字参数:
# 定义一个函数,实现打印个人信息的功能
def my_Info(name, gender, age):
print(f'我的名字是:{name},性别:{gender},今年 {age} 岁')
my_Info('Jock', '男', 25) # 通过位置参数调用 my_Info 函数
my_Info(name='Jock', gender='男', age=25) # 通过关键字参数调用 my_Info 函数