CC++ & Algorithm

Python形参与实参

困难7
语言版本:C++Python
概述:理解函数定义中用来接收数据的“占位符”(形参)和调用时实际传入的“真数据”(实参)的区别。

形参和实参:让函数学会“看人下菜碟”

你有没有见过这样的场景:妈妈做饭,你说“今天我想吃红烧肉”,她就做红烧肉;下次你说“我想吃清蒸鱼”,她就做清蒸鱼。其实妈妈的大脑里有一个“做菜函数”,每次你告诉她菜名(实参),她就按照步骤(函数体)做对应的菜,而菜名那个“空位”(形参)就是你放进去的具体菜名。在Python中,**形参(Parameter)实参(Argument)**就是这样的搭档:形参是函数定义时留的“空位”,实参是调用时真正填进去的“真数据”。

什么是形参?—— 函数定义时的“占位符”

形参(parameter)写在函数定义的小括号里,它只是一个名字,表示将来调用时需要在这里放一个值。就像你在玩具模型上留了一个“插零件的洞”,洞的大小固定,但可以插不同的零件。

def make_juice(fruit):   # fruit 是形参,表示“需要一种水果”
    print("正在榨", fruit, "汁...")
    print(fruit, "汁做好了!")

这里的 fruit 就是形参。函数体内可以用它,但此时它还没有具体值——就像妈妈问你“你想吃什么菜?”但还没点菜时,菜名是空的。

生活中的类似例子

  • 你告诉朋友:“明天请你吃饭,到时候你想吃啥,我就点啥。”——那个“你想吃啥”就是形参。
  • 学校打印奖状:“班级____的同学获得优秀奖。”——空白处就是形参。

什么是实参?—— 调用时填入的“真数据”

实参(argument)是调用函数时,放在小括号里的具体数据。Python会把实参的值复制给对应的形参,然后执行函数体。

make_juice("苹果")   # "苹果" 是实参,传给 fruit

运行结果:

正在榨 苹果 汁...
苹果 汁做好了!

换成不同的实参:

make_juice("橙子")   # 输出:正在榨 橙子 汁... 橙子 汁做好了!
make_juice("西瓜")   # 输出:正在榨 西瓜 汁... 西瓜 汁做好了!

关键点

  • 同一个函数(同一个机器),塞不同的实参(水果),得到不同的结果(果汁)。
  • 形参就像“收件箱上的地址标签”,实参就是“寄给你的那封信”。

多个参数:一个萝卜一个坑

函数可以定义多个形参,调用时要按顺序给实参,一一对应。

def buy_snack(name, price, count):   # 三个形参:零食名、单价、数量
    total = price * count            # 总价 = 单价 × 数量
    print("买了", count, "包", name, ",共", total, "元。")

buy_snack("薯片", 5, 3)   # 实参按顺序:name="薯片", price=5, count=3

输出:

买了 3 包 薯片 ,共 15 元。

常见错误:参数数量不匹配

  • 如果少给一个实参:buy_snack("薯片", 5) → 报错 TypeError: missing 1 required positional argument: 'count'
  • 如果多给一个实参:buy_snack("薯片", 5, 3, "辣味") → 报错 TypeError: takes 3 positional arguments but 4 were given

关键字实参:指名道姓,顺序随便

除了按位置传递,Python还允许你在调用时用“形参名=值”的方式指定实参。这叫关键字实参,好处是顺序可以打乱,而且写得更清楚。

buy_snack(count=2, name="巧克力", price=8)   # 不按顺序,但明确给每个形参赋值
# 输出:买了 2 包 巧克力 ,共 16 元。

什么时候方便?

  • 函数有多个参数,你只记得参数名,不记得顺序。
  • 想让代码容易看懂,比如 make_student(name="小明", age=10, grade=5)make_student("小明", 10, 5) 更清晰。

注意:位置实参和关键字实参可以混用,但位置实参必须放在关键字实参之前。

buy_snack("饼干", count=4, price=3)   # 正确:位置先,关键字后
# buy_snack(count=4, "饼干", price=3)  # 错误!位置实参不能放在关键字后面

形参和实参就像“信箱”和“信”

我们来用一个比喻加深理解:

  • 形参是信箱上的名字(比如“小明收”),它告诉邮递员“把信放这里”。
  • 实参是信里的具体内容,你每次写的信不同,但都投进同一个信箱。
  • 函数体就像收信人读信的过程——无论谁来信,都按同样的方式拆信、看信。

再比如零花钱

def weekly_allowance(day, amount):   # day: 星期几, amount: 金额
    print("今天是星期", day, ",零花钱有", amount, "元。")

weekly_allowance("一", 10)   # 输出:今天是星期 一 ,零花钱有 10 元。
weekly_allowance(day="五", amount=20)  # 输出:今天是星期 五 ,零花钱有 20 元。

新手容易犯的三个错误

  1. 形参名和实参名混淆

    • 以为形参名可以直接当作实参用。例如 def add(x, y): return x+y,调用时写 add(x=3, y=5) 没问题,但要是写成 add(3, y=5) 也正确——混用时注意顺序规则。
    • 更常见的混淆:认为调用时不需要给实参,因为形参看起来像个变量。其实形参只是“空位”,不赋值会报错。
  2. 参数数量不匹配

    • 忘记给某个形参赋值,或者多给了。比如一个函数需要2个参数,调用时只给了1个。解决办法:要么补齐,要么在定义时给形参默认值(后续会学)。
  3. 位置和关键字混用顺序错误

    • 错误:buy_snack(count=4, "可乐", price=3)
    • 正确:所有位置实参必须在关键字实参之前。

完整示例:计算考试平均分

下面是一个完整的程序,用函数计算某次考试的平均分,体会形参和实参的用法。

# 定义计算平均分的函数
def average_score(name, scores):   # name: 学生姓名, scores: 成绩列表
    total = sum(scores)            # 计算总分
    avg = total / len(scores)      # 计算平均分
    print(name, "的平均分是", avg, "分。")
    return avg

# 调用函数,传入实参
student_name = "小美"              # 学生姓名
exam_scores = [88, 92, 76, 95]     # 四次考试的成绩列表
result = average_score(student_name, exam_scores)   # 位置实参传进去
print("最高分的考试是", max(exam_scores), "分。")

# 用关键字实参调用
average_score(scores=[100, 98, 100], name="学霸")   # 输出:学霸 的平均分是 99.0 分。

运行结果:

小美 的平均分是 87.75 分。
最高分的考试是 95 分。
学霸 的平均分是 99.0 分。

相关指引

理解了形参和实参,你就可以开始玩更高级的功能了:

  • 默认参数:给形参一个默认值,调用时可以省去实参(比如 def greet(name="同学"):)。
  • 返回值:用 return 把结果传出来,让函数成为真正的小“计算器”。
  • 局部变量:函数内定义的变量(包括形参)只在函数内部有效,外面看不见。
  • 可变参数:当你不确定有几个实参时,可以用 *args**kwargs 来接收。

继续加油,你已经掌握了函数最重要的“接口”知识。多写多试,很快你就能自己写出处理考试分数、计算零花钱、管理游戏背包等各种有用的小函数了!

例题精讲

1单选题

在Python函数定义中,用于接收调用时传入数据的变量被称为( )。

A实参
B形参
C返回值
D局部变量
2判断题

在Python中,函数调用时,实参的个数必须与形参的个数完全一致,否则会报错。

3填空题
阅读以下代码,在空白处填写输出结果。

def func(x):
    x = 10

a = 5
func(a)
print(a)  # 输出:___
4单选题

关于Python函数的形参与实参,以下说法正确的是( )。

A形参在函数调用时创建,调用结束后销毁
B实参必须是已定义的变量
C关键字参数允许实参按形参名称传递,可以不考虑顺序
D默认参数必须放在形参列表的最前面
5判断题

在Python中,如果函数的实参是列表(可变对象),在函数内部对该列表进行修改(如append),则函数外部的原列表也会发生变化。