Python(十五) 中函数的定义、调用与参数传递
一、什么是函数
函数是一段可以重复使用的代码。
通俗地说,函数就像一个“工具”:
你给它一些数据,它帮你完成一件事情,必要时再把结果返回给你。
生活中的例子:
电饭煲是一个工具。
你放入米和水。
它经过处理。
最后给你一锅米饭。
程序中的函数也是类似的:
输入数据
执行代码
输出结果
例如,我们想计算两个数的和:
def add(a, b):
return a + b
result = add(3, 5)
print(result)
输出结果:
8
这里的 add 就是一个函数。
二、为什么要使用函数
使用函数主要有三个好处:
1. 减少重复代码
2. 让程序结构更清楚
3. 方便后期修改和维护
如果不用函数,代码可能会这样:
print("打开文件")
print("读取内容")
print("关闭文件")
print("打开文件")
print("读取内容")
print("关闭文件")
同样的代码写了两遍。
如果使用函数,可以写成:
def read_file():
print("打开文件")
print("读取内容")
print("关闭文件")
read_file()
read_file()
这样代码更简洁,也更容易理解。
三、函数的定义
在 Python 中,使用 def 关键字定义函数。
基本格式:
def 函数名():
函数体代码
示例:
def say_hello():
print("你好")
这段代码只是定义了一个函数,函数里面的代码还不会马上执行。
可以这样理解:
定义函数:制造一个工具
调用函数:真正使用这个工具
函数定义的组成部分
def say_hello():
print("你好")
可以拆开来看:
def:定义函数的关键字
say_hello:函数名
():参数列表,暂时没有参数也要写
冒号:表示下面开始写函数体
缩进代码:函数体,也就是函数要执行的内容
四、函数的调用
函数定义好以后,如果想让函数执行,需要调用函数。
调用格式:
函数名()
示例:
def say_hello():
print("你好")
say_hello()
输出结果:
你好
如果调用多次,函数就会执行多次:
def say_hello():
print("你好")
say_hello()
say_hello()
say_hello()
输出结果:
你好
你好
你好
五、函数必须先定义,再调用
Python 程序从上往下执行。
所以函数通常要先定义,再调用。
错误写法:
say_hello()
def say_hello():
print("你好")
这样写可能会报错,因为调用函数时,Python 还不知道 say_hello 是什么。
正确写法:
def say_hello():
print("你好")
say_hello()
六、带参数的函数
有些函数执行时需要外部提供数据,这些数据就叫参数。
示例:
def say_hello(name):
print("你好," + name)
say_hello("小明")
say_hello("小红")
输出结果:
你好,小明
你好,小红
这里:
name 是参数。
调用函数时传入的 "小明" 和 "小红" 会交给 name。
可以把参数理解成函数的“输入”。
七、形参和实参
讲函数参数时,经常会遇到两个概念:
形参
实参
1. 形参
形参是定义函数时写在括号里的变量。
示例:
def greet(name):
print("你好," + name)
这里的 name 就是形参。
形参可以理解成:
函数提前准备好的接收位置。
2. 实参
实参是调用函数时真正传进去的数据。
示例:
greet("小明")
这里的 "小明" 就是实参。
实参可以理解成:
真正交给函数处理的数据。
3. 形参和实参的关系
完整示例:
def greet(name):
print("你好," + name)
greet("小明")
解释:
name 是形参。
"小明" 是实参。
调用 greet("小明") 时,"小明" 会传给 name。
八、多个参数
函数可以有一个参数,也可以有多个参数。
示例:计算两个数的和。
def add(a, b):
print(a + b)
add(3, 5)
输出结果:
8
这里:
a 接收 3
b 接收 5
再看一个例子:
def introduce(name, age):
print("我叫", name)
print("今年", age, "岁")
introduce("小明", 18)
输出结果:
我叫 小明
今年 18 岁
九、返回值 return
有些函数只是完成动作,比如打印一句话。
有些函数执行后,还需要把结果交给外部继续使用,这时就要用 return。
1. return 的基本用法
示例:
def add(a, b):
return a + b
result = add(3, 5)
print(result)
输出结果:
8
解释:
return a + b 表示把 a + b 的结果返回出去。
result = add(3, 5) 表示用 result 接收函数返回的结果。
2. print 和 return 的区别
print 是把内容显示在屏幕上。
return 是把结果返回给调用函数的位置。
示例一:使用 print
def add(a, b):
print(a + b)
result = add(3, 5)
print("结果是:", result)
输出结果:
8
结果是: None
原因:
函数里面只是 print 了结果,没有 return。
所以 result 得到的是 None。
示例二:使用 return
def add(a, b):
return a + b
result = add(3, 5)
print("结果是:", result)
输出结果:
结果是: 8
教学时可以这样讲:
print 是“展示结果”。
return 是“交出结果”。
3. return 会结束函数
函数执行到 return 后,函数会立即结束。
示例:
def test():
print("第一行")
return
print("第二行")
test()
输出结果:
第一行
return 后面的 print("第二行") 不会执行。
4. 函数没有 return 时默认返回 None
示例:
def say_hello():
print("你好")
result = say_hello()
print(result)
输出结果:
你好
None
因为 say_hello() 没有写 return,所以默认返回 None。
十、位置参数
位置参数是最常见的参数传递方式。
它的特点是:按照位置顺序传递参数。
示例:
def introduce(name, age):
print("姓名:", name)
print("年龄:", age)
introduce("小明", 18)
这里:
"小明" 传给第一个参数 name
18 传给第二个参数 age
如果顺序写反,结果也会变:
introduce(18, "小明")
输出可能变成:
姓名: 18
年龄: 小明
所以使用位置参数时,要注意顺序。
十一、关键字参数
关键字参数是在调用函数时,明确写出参数名。
示例:
def introduce(name, age):
print("姓名:", name)
print("年龄:", age)
introduce(name="小明", age=18)
也可以交换顺序:
introduce(age=18, name="小明")
因为已经写明了参数名,所以顺序不容易出错。
教学时可以这样讲:
位置参数靠顺序。
关键字参数靠名字。
十二、默认参数
默认参数是在定义函数时,给参数提前设置一个默认值。
如果调用函数时没有传这个参数,就使用默认值。
示例:
def greet(name, city="北京"):
print(name, "来自", city)
greet("小明")
greet("小红", "上海")
输出结果:
小明 来自 北京
小红 来自 上海
解释:
第一次调用时,没有传 city,所以使用默认值 "北京"。
第二次调用时,传入了 "上海",所以使用 "上海"。
默认参数的位置
默认参数通常要放在普通参数后面。
错误写法:
def greet(city="北京", name):
print(name, city)
正确写法:
def greet(name, city="北京"):
print(name, city)
十三、可变参数 *args
有时候,我们不确定调用函数时会传入多少个参数。
这时可以使用 *args。
*args 可以接收多个位置参数,并把它们保存成一个元组。
示例:
def add_all(*args):
total = 0
for num in args:
total = total + num
return total
print(add_all(1, 2, 3))
print(add_all(1, 2, 3, 4, 5))
输出结果:
6
15
解释:
add_all(1, 2, 3) 中,args 是 (1, 2, 3)。
add_all(1, 2, 3, 4, 5) 中,args 是 (1, 2, 3, 4, 5)。
注意:
args 这个名字不是固定的,但大家习惯这样写。
真正起作用的是前面的星号 *。
十四、可变关键字参数 **kwargs
**kwargs 可以接收多个关键字参数,并把它们保存成一个字典。
示例:
def show_info(**kwargs):
print(kwargs)
show_info(name="小明", age=18, city="北京")
输出结果:
{'name': '小明', 'age': 18, 'city': '北京'}
解释:
kwargs 是一个字典。
键是参数名,值是传入的数据。
也可以遍历它:
def show_info(**kwargs):
for key, value in kwargs.items():
print(key, "=", value)
show_info(name="小明", age=18)
输出结果:
name = 小明
age = 18
注意:
kwargs 这个名字不是固定的,但大家习惯这样写。
真正起作用的是前面的两个星号 **。
十五、参数的常见顺序
如果一个函数同时使用多种参数,通常顺序是:
def 函数名(普通参数, 默认参数, *args, **kwargs):
函数体
示例:
def show(a, b=10, *args, **kwargs):
print("a =", a)
print("b =", b)
print("args =", args)
print("kwargs =", kwargs)
show(1, 2, 3, 4, name="小明", age=18)
输出结果:
a = 1
b = 2
args = (3, 4)
kwargs = {'name': '小明', 'age': 18}
初学阶段不一定要立刻掌握复杂组合,但要知道它们的基本含义。
十六、参数解包
有时候,数据已经放在列表、元组或字典里,可以使用解包的方式传给函数。
1. 使用 * 解包列表或元组
示例:
def add(a, b):
return a + b
numbers = [3, 5]
result = add(*numbers)
print(result)
输出结果:
8
解释:
add(*numbers) 相当于 add(3, 5)。
2. 使用 ** 解包字典
示例:
def introduce(name, age):
print("姓名:", name)
print("年龄:", age)
student = {"name": "小明", "age": 18}
introduce(**student)
解释:
introduce(**student) 相当于 introduce(name="小明", age=18)。
十七、参数传递中的可变与不可变
这是函数参数中比较容易让学生困惑的地方。
Python 中常见的数据可以分为两类:
不可变类型:int、float、str、tuple
可变类型:list、dict、set
1. 不可变类型作为参数
示例:
def change_num(x):
x = 100
num = 10
change_num(num)
print(num)
输出结果:
10
解释:
函数里面让 x 变成 100,不会改变外面的 num。
2. 可变类型作为参数
示例:
def add_item(items):
items.append("Python")
courses = ["语文", "数学"]
add_item(courses)
print(courses)
输出结果:
['语文', '数学', 'Python']
解释:
列表是可变对象。
函数里面对列表进行了 append 操作,外面的列表也会受到影响。
教学时可以这样讲:
传入普通数字、字符串时,函数里重新赋值通常不会影响外面。
传入列表、字典时,如果函数里修改了里面的内容,外面也会看到变化。
3. 如果不想修改原列表,可以复制一份
示例:
def add_item(items):
new_items = items.copy()
new_items.append("Python")
return new_items
courses = ["语文", "数学"]
new_courses = add_item(courses)
print(courses)
print(new_courses)
输出结果:
['语文', '数学']
['语文', '数学', 'Python']
十八、变量作用域
变量作用域指变量能在哪些地方使用。
函数中常见两种变量:
局部变量
全局变量
1. 局部变量
局部变量是在函数内部定义的变量,只能在函数内部使用。
示例:
def test():
name = "小明"
print(name)
test()
这里的 name 是局部变量。
如果在函数外面使用它,会报错:
def test():
name = "小明"
test()
print(name)
2. 全局变量
全局变量是在函数外部定义的变量。
示例:
name = "小明"
def test():
print(name)
test()
函数内部可以读取全局变量。
3. 不建议随意修改全局变量
如果函数中要修改全局变量,需要使用 global。
示例:
count = 0
def add_count():
global count
count = count + 1
add_count()
print(count)
输出结果:
1
但是教学时要提醒学生:
不要随意使用 global。
函数最好通过参数接收数据,通过 return 返回结果。
这样代码更清楚,也更容易维护。
十九、函数命名建议
函数名应该清楚表达函数的作用。
不太清楚的写法:
def f():
print("你好")
更清楚的写法:
def say_hello():
print("你好")
常见函数命名习惯:
使用小写字母
多个单词之间用下划线连接
函数名通常使用动词或动词短语
示例:
def get_score():
pass
def calculate_total():
pass
def print_student_info():
pass
二十、常见注意事项
1. 定义函数要使用 def
错误写法:
function say_hello():
print("你好")
正确写法:
def say_hello():
print("你好")
2. 函数名后面要有括号和冒号
错误写法:
def say_hello
print("你好")
正确写法:
def say_hello():
print("你好")
3. 函数体必须缩进
错误写法:
def say_hello():
print("你好")
正确写法:
def say_hello():
print("你好")
通常使用 4 个空格作为一级缩进。
4. 定义函数不会自动执行
示例:
def say_hello():
print("你好")
这段代码只定义了函数,不会输出“你好”。
必须调用函数:
say_hello()
5. 参数数量要对应
示例:
def add(a, b):
return a + b
add(3)
这会报错,因为函数需要两个参数,但只传了一个。
正确写法:
add(3, 5)
6. 默认参数不要随便使用可变对象
这是 Python 函数中很常见的坑。
不推荐:
def add_student(name, students=[]):
students.append(name)
return students
更推荐:
def add_student(name, students=None):
if students is None:
students = []
students.append(name)
return students
原因可以简单解释为:
默认参数只会在函数定义时创建一次。
如果默认值是列表,后面多次调用可能会共用同一个列表。
初学阶段可以先记住:
默认参数尽量不要直接写 [] 或 {}。
7. return 后面的代码不会继续执行
示例:
def test():
return "结束"
print("这一行不会执行")
return 后面的代码不会执行。
8. print 不是 return
函数中打印了结果,不代表函数返回了结果。
示例:
def add(a, b):
print(a + b)
result = add(1, 2)
print(result)
输出中会出现 None,因为函数没有返回值。
9. 函数功能不要太复杂
一个函数最好只完成一件明确的事情。
不太清楚的函数:
def do_everything():
pass
更清楚的函数:
def read_score():
pass
def calculate_average():
pass
def print_report():
pass
教学时可以提醒学生:
函数不是越长越好。
函数越清楚,程序越容易理解。
二十一、课堂示例
示例 1:定义并调用无参数函数
def show_menu():
print("1. 添加学生")
print("2. 删除学生")
print("3. 查询学生")
show_menu()
讲解重点:
def 定义函数。
show_menu() 调用函数。
示例 2:带参数的问候函数
def greet(name):
print("你好," + name)
greet("小明")
greet("小红")
讲解重点:
参数让函数可以处理不同的数据。
示例 3:计算两个数的和
def add(a, b):
return a + b
result = add(10, 20)
print("结果是:", result)
讲解重点:
return 把计算结果返回出来。
外部可以继续使用这个结果。
示例 4:判断成绩是否及格
def check_score(score):
if score >= 60:
return "及格"
else:
return "不及格"
result = check_score(85)
print(result)
讲解重点:
函数中可以使用 if 分支语句。
不同条件可以返回不同结果。
示例 5:求多个数的和
def add_all(*args):
total = 0
for num in args:
total = total + num
return total
print(add_all(1, 2, 3))
print(add_all(10, 20, 30, 40))
讲解重点:
*args 可以接收不确定数量的位置参数。
示例 6:显示学生信息
def show_student(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
show_student(name="小明", age=18, class_name="三年级一班")
讲解重点:
**kwargs 可以接收不确定数量的关键字参数。
二十二、课堂练习
练习 1:写一个打招呼函数
要求:定义一个函数 hello(),调用后输出“欢迎学习 Python”。
参考代码:
def hello():
print("欢迎学习 Python")
hello()
练习 2:写一个带姓名的打招呼函数
要求:传入一个姓名,输出“你好,某某”。
参考代码:
def greet(name):
print("你好," + name)
greet("小明")
练习 3:写一个求和函数
要求:传入两个数,返回它们的和。
参考代码:
def add(a, b):
return a + b
result = add(3, 5)
print(result)
练习 4:写一个判断奇偶数的函数
要求:传入一个整数,返回“偶数”或“奇数”。
参考代码:
def check_number(num):
if num % 2 == 0:
return "偶数"
else:
return "奇数"
result = check_number(8)
print(result)
练习 5:写一个计算平均分的函数
要求:传入多个成绩,返回平均分。
参考代码:
def average(*scores):
total = 0
for score in scores:
total = total + score
return total / len(scores)
result = average(80, 90, 100)
print(result)
二十三、教学建议
讲解函数时,可以按照下面顺序:
1. 先用生活中的工具解释函数
2. 说明为什么要使用函数
3. 讲 def 定义函数
4. 讲函数调用
5. 讲参数,也就是给函数输入数据
6. 讲 return,也就是让函数交出结果
7. 讲位置参数、关键字参数、默认参数
8. 最后补充 *args、**kwargs 和常见错误
可以用下面的问题引导学生:
如果一段代码要重复使用很多次,能不能只写一遍?
如果同一个功能要处理不同的人名,应该怎么传入人名?
如果函数计算出了结果,怎么把结果交给外面继续使用?
print 和 return 是不是一回事?
教学重点建议放在:
函数定义
函数调用
形参和实参
return 返回值
位置参数
关键字参数
默认参数
参数传递中的可变与不可变
*args 和 **kwargs 可以作为拓展内容,不必在第一节课讲得太深。
二十四、总结
函数是 Python 中非常重要的基础内容。
它可以把一段代码封装起来,需要时反复调用。
可以这样记:
def:定义函数
函数名():调用函数
参数:给函数传入数据
return:让函数返回结果
函数参数常见形式:
位置参数:按照顺序传递
关键字参数:按照参数名传递
默认参数:没有传值时使用默认值
*args:接收多个位置参数
**kwargs:接收多个关键字参数
学习函数时,最重要的几个点是:
1. 函数要先定义,再调用
2. 定义函数不会自动执行
3. 参数数量和顺序要注意
4. print 是显示结果,return 是返回结果
5. 可变对象作为参数时,函数内部修改可能影响外部
6. 函数功能要清楚,不要写得过于复杂
一句话总结:
函数让代码可以被重复使用,也让程序结构更清晰,是从“会写代码”走向“会组织代码”的重要一步。