嗨,小伙伴们!欢迎回来!在上一节课中,我们学会了用列表、字典这些数据结构来管理数据。现在你已经能存储各种信息了,但你可能发现,如果同样的代码要写好几遍,不仅麻烦,而且显得很笨拙。比如你要多次计算圆的面积,每次都写一遍 3.14 * 半径 * 半径,多累啊!今天我们就来学习Python中的函数,它就像一个“魔法盒子”,可以把一段代码打包起来,需要的时候随时调用,让你的编程事半功倍!
一、为什么需要函数?
想象一下,你要给朋友们做很多杯奶茶。如果没有机器,你得一杯一杯地手动煮茶、加奶、加糖……累死了!但如果你有一台全自动奶茶机,只要按一下按钮,就能自动做出一杯奶茶,是不是轻松多了?
函数就是程序里的“奶茶机”。你把要做的事情(比如计算圆的面积、判断一个数是不是质数)写进函数里,以后每次需要的时候,只需要“按一下按钮”(调用函数),它就会自动帮你完成,省时省力,还不会出错。
使用函数有三大好处:
避免重复代码 —— 同样的逻辑只写一次,想用就调用。
逻辑清晰 —— 把复杂任务拆分成一个个小函数,程序更容易读懂。
便于维护 —— 如果某个功能需要修改,只需要改函数内部,所有调用它的地方都会自动更新。
二、定义和调用函数:先造机器,再按按钮
2.1 定义函数
用 def 关键字来定义函数,后面跟着函数名、括号和冒号。函数名要能表达函数的功能,比如 say_hello、calculate_area。
python
defsay_hello():print("你好,世界!")print("欢迎来到Python函数的世界!")这个函数名叫 say_hello,它没有参数(括号里是空的),功能就是打印两行文字。
注意:函数定义本身不会执行代码,它只是创建了一个“机器”。要让它干活,必须调用它。
2.2 调用函数
调用函数很简单,写上函数名加上括号就行:
python
say_hello()# 调用函数
运行结果:
text
你好,世界!欢迎来到Python函数的世界!
你可以多次调用,每次都会执行里面的代码:
python
say_hello()say_hello()# 输出两遍同样的内容
三、函数的参数:让机器根据输入干活
很多时候,我们希望函数能根据不同的输入做不同的事情。比如“做奶茶”的机器,你告诉它“加珍珠”,它就做珍珠奶茶;你告诉它“加椰果”,它就做椰果奶茶。这个“输入”就是参数。
3.1 位置参数
最简单的参数就是位置参数,调用时按顺序传入值:
python
defgreet(name):print(f"你好,{name}!")greet("小明")# 输出:你好,小明!greet("小红")# 输出:你好,小红!参数 name 在定义时写在括号里,调用时传入的实际值("小明"、"小红")会赋值给 name。
多个参数用逗号分隔:
python
defintroduce(name, age):print(f"我叫{name},今年{age}岁。")introduce("小刚",18)# 输出:我叫小刚,今年18岁。顺序很重要:第一个参数对应 name,第二个对应 age。
3.2 默认参数
有时候某些参数的值比较固定,可以给它一个默认值,调用时如果不传,就使用默认值:
python
defmake_drink(base="奶茶", topping="珍珠"):print(f"制作一杯{base},加{topping}。")make_drink()# 输出:制作一杯奶茶,加珍珠。make_drink("咖啡")# 输出:制作一杯咖啡,加珍珠。(第一个参数按顺序覆盖base)make_drink(topping="椰果")# 输出:制作一杯奶茶,加椰果。(指定参数名,跳过base)make_drink("果汁","芦荟")# 输出:制作一杯果汁,加芦荟。注意:带默认值的参数必须放在不带默认值的参数后面,否则会报错。比如 def func(a=1, b): 是错误的。
3.3 关键字参数
调用函数时,可以通过参数名指定传入的值,这样可以不按顺序:
python
defstudent_info(name, age, city):print(f"{name},{age}岁,来自{city}。")student_info(city="上海", name="小丽", age=20)# 输出:小丽,20岁,来自上海。关键字参数让代码更清晰,尤其当参数很多时。
3.4 不定长参数
有时候你也不知道函数会收到多少个参数,可以用 *args 和 **kwargs 来接收。
*args 把多余的位置参数打包成元组
**kwargs 把多余的关键字参数打包成字典
python
defmake_friends(name,*hobbies,**info):print(f"{name}的兴趣爱好:")for hobby in hobbies:print(f"- {hobby}")print("其他信息:")for key, value in info.items():print(f"{key}: {value}")make_friends("小明","读书","游泳","编程", age=18, city="北京")运行结果:
text
小明的兴趣爱好:- 读书- 游泳- 编程其他信息:age: 18city: 北京
四、函数的返回值:让机器给你结果
函数执行完可以给你一个结果,用 return 语句返回。比如“计算器”函数,你输入两个数,它返回计算结果。
python
defadd(a, b): result = a + breturn resultsum= add(3,5)print(sum)# 输出:8
return 后面的值就是函数的输出,可以赋值给变量,也可以直接使用。
如果没有 return,函数默认返回 None(表示啥也没有)。
4.1 返回多个值
Python 函数可以返回多个值,实际上返回的是一个元组:
python
defget_name_and_age(): name ="小强" age =22return name, ageresult = get_name_and_age()print(result)# 输出:('小强', 22)print(type(result))# 输出:<class 'tuple'># 可以直接解包n, a = get_name_and_age()print(n)# 小强print(a)# 22五、变量作用域:函数里的变量外面能用吗?
函数内部定义的变量,只能在函数内部使用,这叫局部变量。函数外部定义的变量,是全局变量,可以在任何地方访问(但要注意)。
python
x =10# 全局变量deftest(): y =5# 局部变量print(x)# 可以访问全局变量print(y)test()print(x)# 可以# print(y) # 这行会报错:NameError,因为y是局部变量
如果在函数内部要修改全局变量,需要用 global 声明:
python
count =0defincrement():global count count +=1increment()increment()print(count)# 输出:2
不过,一般不推荐随意修改全局变量,容易导致程序混乱。最好通过参数传递和返回值来操作。
六、匿名函数(lambda):小巧的一次性函数
有时候你只需要一个简单的函数,而且只用一次,可以用 lambda 表达式快速定义。lambda 函数没有名字,直接返回结果。
语法:lambda 参数: 表达式
python
# 定义一个求平方的lambda函数square =lambda x: x **2print(square(5))# 输出:25# 通常用在需要函数作为参数的地方,比如 sorted 的 keystudents =[("小明",18),("小红",20),("小刚",15)]students.sort(key=lambda s: s[1])# 按年龄排序print(students)# 输出:[('小刚', 15), ('小明', 18), ('小红', 20)]lambda 适合简单逻辑,复杂逻辑还是用 def 定义更清晰。
七、综合案例:学生成绩计算器
把今天学的函数知识串起来,写一个学生成绩计算器:
python
defget_grade(score):"""根据分数返回等级"""if score >=90:return"A"elif score >=80:return"B"elif score >=70:return"C"elif score >=60:return"D"else:return"F"defaverage(scores):"""计算平均分"""returnsum(scores)/len(scores)defshow_student_info(name, scores):"""显示单个学生的信息"""print(f"学生:{name}")print(f" 语文:{scores[0]} ({get_grade(scores[0])})")print(f" 数学:{scores[1]} ({get_grade(scores[1])})")print(f" 英语:{scores[2]} ({get_grade(scores[2])})") avg = average(scores)print(f" 平均分:{avg:.1f} ({get_grade(avg)})")defclass_report(students):"""全班成绩报告"""print("="*40)print("班级成绩报告")print("="*40) total_scores =[]for name, scores in students.items(): show_student_info(name, scores) total_scores.extend(scores)print("-"*40) class_avg = average(total_scores)print(f"全班平均分:{class_avg:.1f} ({get_grade(class_avg)})")# 数据students ={"小明":[85,92,78],"小红":[90,88,95],"小刚":[78,85,82],"小丽":[92,96,89]}# 调用函数生成报告class_report(students)运行结果:
text
========================================班级成绩报告========================================学生:小明 语文:85 (B) 数学:92 (A) 英语:78 (C) 平均分:85.0 (B)学生:小红 语文:90 (A) 数学:88 (B) 英语:95 (A) 平均分:91.0 (A)学生:小刚 语文:78 (C) 数学:85 (B) 英语:82 (B) 平均分:81.7 (B)学生:小丽 语文:92 (A) 数学:96 (A) 英语:89 (B) 平均分:92.3 (A)----------------------------------------全班平均分:87.4 (B)
这个程序用了多个函数:get_grade、average、show_student_info、class_report。每个函数负责一个独立的任务,组合起来就完成了复杂的报表生成。
八、新手避坑指南
8.1 常见错误及解决方法
| | |
|---|
| def hello(): print("hi")
| |
| 定义 def add(a,b): 调用 add(5) | |
| count=0
def inc(): count+=1 | |
| def add(a,b): c=a+b
| |
| def test(): return 1; print("hi") | |
| def func(lst=[]) | 默认值如果是列表,多次调用会累积,建议用 None 并在内部创建 |
8.2 三个实用小贴士
用文档字符串(docstring)说明函数:在函数开头用三个引号写注释,方便自己和他人理解。
python
defadd(a, b):"""返回两个数的和"""return a + b
可以用 help(add) 查看。
函数应该只做一件事:如果一个函数做了太多事,考虑拆分成几个小函数。
用 pass 占位:如果还没想好函数内部怎么写,先用 pass 占位,程序不会报错。
python
deffuture_function():pass# 以后再实现
九、总结与下一步
恭喜你!现在你已经掌握了Python函数的核心技能:
✅ 定义和调用函数:用 def 造机器,用 () 按按钮
✅ 参数传递:位置参数、默认参数、关键字参数、不定长参数
✅ 返回值:用 return 拿到结果
✅ 变量作用域:分清全局和局部
✅ lambda函数:简洁的匿名函数
函数是组织代码的基石,用好函数能让程序变得简洁、清晰、易维护。就像搭积木一样,把一个个小函数拼起来,就能搭建出强大的程序。
下一步,我们将学习文件操作——怎么把数据保存到文件里,或者从文件里读取数据。这样你的程序就能“记住”东西,重启之后也不会丢失!
记住那句老话:编程不是看会的,而是练会的。赶紧打开你的Python环境,把文中的例子亲手敲一遍,再试着修改参数、增加功能,看看会发生什么有趣的变化。有任何问题,欢迎在评论区留言交流!
下期预告:Python文件操作:让程序拥有“记忆”,数据保存与读取轻松搞定!敬请期待!