第11课:函数参数(位置、关键字、默认值)
学习目标
完成本课学习后,你将能够:
- 清晰区分位置参数、关键字参数和默认值参数。
- 掌握在函数定义和调用时正确使用这三种参数类型。
- 理解并遵守关键字参数必须在位置参数之后的规则。
- 能够运用所学的参数知识,编写灵活、可读性更强的函数。
核心概念
在上一课中,我们学会了如何定义和调用一个基础函数。当一个函数需要"原材料"来工作时,这些原材料就是参数。给函数传递参数有几种不同的方式,就像点菜一样:
- 位置参数(Positional Arguments):就像你按菜单顺序点菜。"来一份宫保鸡丁,一碗米饭"。顺序不能错,第一个是宫保鸡丁,第二个是米饭。在函数调用时,参数的值会按顺序依次赋给函数定义中的参数变量。
- 关键字参数(Keyword Arguments):就像你明确说出菜名和你的特殊要求。"米饭要一碗,宫保鸡丁少放辣"。你通过"关键字"(如
米饭=、宫保鸡丁=)明确指定了每个参数的值,顺序就无所谓了。这让代码意图更清晰。 - 默认值参数(Default Arguments):就像菜单上写着"推荐做法:微辣"。如果你不特别说明,厨师就按默认的"微辣"来做。在函数定义时,你可以为某些参数预设一个默认值。调用时,如果提供了该参数的值,就用提供的;否则,就用默认值。
代码示例
让我们通过一个制作三明治的函数来理解这些概念。
# 定义一个函数:制作三明治
def make_sandwich(bread, filling, sauce='mayo'):
"""
根据给定的食材制作一个三明治。
:param bread: 面包类型 (位置参数)
:param filling: 馅料 (位置参数)
:param sauce: 酱料,默认为蛋黄酱 (默认值参数)
"""
print(f"正在制作三明治:")
print(f" 面包:{bread}")
print(f" 馅料:{filling}")
print(f" 酱料:{sauce}")
print("美味的三明治做好了!\n")
# 1. 使用位置参数调用 (顺序很重要: bread, filling, sauce)
print("--- 使用位置参数 ---")
make_sandwich('全麦面包', '金枪鱼', '千岛酱')
make_sandwich('白面包', '火腿') # 使用默认酱料 (mayo)
# 2. 使用关键字参数调用 (顺序不重要,名称要正确)
print("--- 使用关键字参数 ---")
make_sandwich(filling='生菜和番茄', bread='黑麦面包', sauce='蜂蜜芥末')
make_sandwich(sauce='番茄酱', filling='烤牛肉', bread='法棍') # 顺序完全不同
# 3. 混合使用位置参数和关键字参数 (关键规则:位置参数必须在关键字参数之前!)
print("--- 混合使用参数 (正确) ---")
make_sandwich('全麦面包', filling='鸡蛋', sauce='蛋黄酱')
# 第一个参数用位置,后两个用关键字。这是允许的。
# 4. 错误示例:位置参数不能在关键字参数之后
# print("--- 混合使用参数 (错误) ---")
# make_sandwich(bread='全麦面包', '金枪鱼', '千岛酱') # 这行会报错:SyntaxError
运行结果:
--- 使用位置参数 ---
正在制作三明治:
面包:全麦面包
馅料:金枪鱼
酱料:千岛酱
美味的三明治做好了!
正在制作三明治:
面包:白面包
馅料:火腿
酱料:mayo
美味的三明治做好了!
--- 使用关键字参数 ---
正在制作三明治:
面包:黑麦面包
馅料:生菜和番茄
酱料:蜂蜜芥末
美味的三明治做好了!
正在制作三明治:
面包:法棍
馅料:烤牛肉
酱料:番茄酱
美味的三明治做好了!
--- 混合使用参数 (正确) ---
正在制作三明治:
面包:全麦面包
馅料:鸡蛋
酱料:蛋黄酱
美味的三明治做好了!
实践练习
- 基础练习:定义一个函数
greet_user,它需要两个参数:name(姓名)和message(问候语,如"你好"、"早上好")。使用位置参数和关键字参数分别调用该函数,观察输出。 - 默认值练习:修改上面的
greet_user函数,给message参数一个默认值'你好'。然后测试以下调用:greet_user('小明')greet_user('小红', '晚上好')greet_user(name='小华', message='下午好')
- 综合应用:编写一个函数
calculate_total,它接收三个参数:price(单价)、quantity(数量,默认值为1)、discount(折扣率,默认值为1.0,即无折扣)。函数应计算并打印总价。测试用例:单价100,数量3,折扣0.9;单价50,数量1(使用默认)。
常见错误
- 遗漏必需参数:调用函数时,没有为所有没有默认值的参数提供值。
def say_hello(name, greeting): print(f"{greeting}, {name}!") # say_hello() # TypeError: say_hello() missing 2 required positional arguments: 'name' and 'greeting' - 位置参数在关键字参数之后:这是Python的语法规则,顺序必须严格遵守。
def func(a, b): pass # func(a=1, 2) # SyntaxError: positional argument follows keyword argument - 使用可变对象作为默认值:这是一个经典陷阱。不要使用列表、字典等可变对象作为默认参数,因为它们只在函数定义时创建一次,后续调用会共享同一个对象。
def bad_append(item, my_list=[]): my_list.append(item) print(my_list) bad_append(1) # 输出 [1] bad_append(2) # 输出 [1, 2],而不是期望的 [2] # 正确做法是使用 None 作为默认值,在函数内部判断并初始化。 def good_append(item, my_list=None): if my_list is None: my_list = [] my_list.append(item) print(my_list)
小结
本课我们深入学习了函数的三种参数类型:
- 位置参数:最基本的参数,按顺序传递,数量必须匹配。
- 关键字参数:通过
键=值的形式传递,顺序无关,极大提高了代码可读性。 - 默认值参数:在定义函数时为参数预设值,使得函数调用更灵活,可以省略具有合理默认值的参数。
关键规则:在函数调用时,所有的位置参数必须出现在关键字参数之前。默认值参数最好放在参数列表的末尾。
理解并熟练运用这些参数类型,将使你能够编写出接口清晰、易于使用和维护的函数,这是迈向更高级编程技巧的重要一步。下一课,我们将学习函数的"输出"——返回值,以及至关重要的变量作用域概念。
练习编辑器
python
Loading...