零基础学 Python 第9章 | 函数基础:def、参数与返回值
本章摘要核心目标学会用def定义函数把代码打包成可复用的工具核心知识点def定义函数、形参与实参、return返回值、多返回值、函数调用流程、参数默认值实操产出封装温度转换、BMI计算、密码强度检测三个实用函数工具集前置基础第8章字符串格式化、第3章if条件判断、变量与数据类型一、写在前面上一章我们学了字符串的各种操作——拼接、格式化、切片、常用方法。你有没有发现一个问题前面写的所有代码都是一条一条堆在一起的从上往下依次执行。这在简单程序里没问题但想象一下你写了一段 20 行的成绩判定逻辑今天要用明天还要用换个班级又要用。你是每次都复制粘贴这 20 行吗万一逻辑要改你改一处还是改十处函数就是解决这个问题的。把一段代码打包起来起个名字以后只要喊这个名字整段代码就会运行。就像家里买了个微波炉——你不用每次都从头造一个只要按一下按钮它就帮你加热。本章是第三部分函数篇的第一章。从这里开始你的代码将从堆指令进化为造工具。二、什么是函数一句话函数就是给一段代码起个名字需要时调用这个名字就能执行那段代码。你其实已经用过函数了。print()、input()、len()——这些都是 Python 内置的函数别人帮你打包好的你直接用就行。现在你要学的是自己造函数。函数有三个核心要素要素说明类比输入参数函数需要的数据微波炉里放的食物处理函数体函数内部执行的代码微波炉加热的过程输出返回值函数执行完给出的结果加热好的食物不是所有函数都有输入和输出但每个函数都有函数体要执行的代码。三、用 def 定义函数定义函数的关键字是def格式如下def函数名():函数体要执行的代码来写第一个属于自己的函数defgreet():print(你好欢迎学习Python)# 调用函数greet()运行结果你好欢迎学习Python定义了不会自动执行。def只是告诉 Python 有这么一个函数只有调用它写一次函数名加括号greet()里面的代码才会运行。你可以调用多次defgreet():print(你好欢迎学习Python)greet()# 第1次调用greet()# 第2次调用greet()# 第3次调用运行结果你好欢迎学习Python 你好欢迎学习Python 你好欢迎学习Python注意函数定义必须写在调用之前。Python 从上往下读代码如果先调用再定义会报找不到这个函数的错误。四、形参与实参让函数接收数据4.1 为什么要传参数上面的greet()每次打印的内容都一样。如果我想对小明说你好对小红也说你好但名字不同呢总不能为每个人写一个函数。参数就是让函数接收外部数据同一个函数处理不同的输入。4.2 定义带参数的函数defgreet(name):print(f你好{name}欢迎学习Python)greet(小明)greet(小红)运行结果你好小明欢迎学习Python 你好小红欢迎学习Python4.3 形参 vs 实参这两个术语新手容易混但其实很简单术语位置作用例子形参形式参数函数定义时的括号里占位符表示这里需要一个数据def greet(name)中的name实参实际参数调用函数时的括号里真正传入的具体数据greet(小明)中的小明一句话记定义时写形参调用时传实参。形参是个变量名实参是具体值调用时实参会赋值给形参。4.4 多个参数函数可以有多个参数用逗号隔开defintroduce(name,age,city):print(f我叫{name}今年{age}岁来自{city})introduce(小明,18,北京)运行结果我叫小明今年18岁来自北京参数的顺序很重要。调用时实参会按顺序一一对应第一个实参给第一个形参第二个给第二个……所以小明对应name18对应age北京对应city。五、return返回值让函数给出结果5.1print和return的区别这是新手最容易搞混的地方。print()—— 把结果显示到屏幕上但程序内部拿不到这个值return—— 把结果交还给调用处程序内部可以继续使用看个例子# 用 print只显示拿不到结果defadd_print(a,b):print(ab)# 用 return把结果交还可以继续用defadd_return(a,b):returnab# 调用对比add_print(3,5)# 屏幕显示 8resultadd_return(3,5)# result 拿到了 8print(result)# 屏幕显示 8print(result*2)# 屏幕显示 16能继续用运行结果8 8 16结论需要拿到函数的结果继续用就用return只是想显示一下用print就行。实际开发中绝大多数函数用return。5.2 return 的特点defcheck_age(age):ifage18:return成年return未成年resultcheck_age(20)print(result)# 成年return有两个作用返回一个值给调用处立即结束函数——return之后的代码不会执行deftest():print(第1行)return结束了print(第2行)# 这行永远不会执行print(test())运行结果第1行 结束了5.3 没有 return 的函数如果函数里没写returnPython 会自动返回None空值defsay_hello():print(你好)resultsay_hello()print(result)# None运行结果你好 NoneNone表示什么都没有。函数不写return就等于return None这是 Python 的默认行为。六、多返回值一次返回多个结果Python 有个很方便的特性函数可以一次返回多个值用逗号隔开。defget_score_info(name,chinese,math):totalchinesemath averagetotal/2returnname,total,average# 接收时也用逗号隔开一一对应name,total,avgget_score_info(小明,85,90)print(f{name}总分{total}平均分{avg})运行结果小明总分175平均分87.5原理Python 的多返回值其实是返回了一个元组tuple接收时自动拆开。你暂时不用管元组是什么记住返回几个值就用几个变量接就行。多返回值在实战中非常常用。比如一个函数既要返回计算结果又要返回状态信息成功/失败用一个 return 搞定。七、函数调用流程程序是怎么跑的理解函数调用的执行顺序对后面排错非常重要。来看一段代码的执行过程defcalculate_bmi(weight,height):计算BMI指数bmiweight/(height**2)returnround(bmi,1)# 主程序print(开始计算)resultcalculate_bmi(70,1.75)print(f你的BMI是{result})print(计算结束)执行流程第1-4行Python 读到def记住有这个函数但不执行函数体第7行执行print(开始计算)→ 屏幕显示开始计算第8行调用calculate_bmi(70, 1.75)→ 跳进函数内部函数内weight 70height 1.75计算bmi 70 / (1.75 ** 2) 22.9return round(bmi, 1)→ 把 22.9 交还给调用处跳出函数第8行result拿到 22.9第9行执行print(f你的BMI是{result})→ 屏幕显示第10行执行print(计算结束)→ 屏幕显示运行结果开始计算 你的BMI是22.9 计算结束关键理解调用函数时程序会暂停主程序跳进函数里执行执行完遇到return 或函数体结束再跳回主程序继续往下走。就像你正在做饭发现需要酱油停下来去拿酱油拿回来继续做。八、参数默认值让参数可选8.1 什么是默认值有时候函数的某个参数大部分情况下取值都一样每次调用都要写一遍很烦。Python 允许你给参数设置默认值defgreet(name,greeting你好):print(f{greeting}{name})# 不传 greeting自动用默认值你好greet(小明)# 你好小明# 传了 greeting用传入的值greet(小明,嗨)# 嗨小明运行结果你好小明 嗨小明8.2 默认值的位置规则有默认值的参数必须放在没有默认值的参数后面# ✅ 正确有默认值的在后defgreet(name,greeting你好):print(f{greeting}{name})# ❌ 错误有默认值的在前# def greet(greeting你好, name):# print(f{greeting}{name})为什么因为 Python 按位置匹配参数如果默认参数在前面调用时 Python 就分不清你传的值到底给谁。记住这个规则普通参数在前默认参数在后。默认参数的更多用法比如*args、**kwargs会在下一章详细讲这里先掌握基本用法。九、Scratch 积木对照ScratchPython说明「自制积木」→ 定义积木def 函数名():把一段代码封装成可复用的积木积木的「输入项」def 函数名(参数):给积木添加输入项对应函数参数# Scratch「自制积木」→ Pythondefsay_hello(name):print(f你好{name})say_hello(小明)Scratch 里点自制积木创建一个新积木可以添加输入项数字、文本等Python 里用def定义函数括号里写参数。调用时 Scratch 拖出积木块Python 写函数名加括号。十、综合实战封装实用小工具集把本章学的函数定义、参数、返回值、多返回值结合前面的 if 条件判断和字符串格式化封装三个实用小工具。完整源码# # 封装实用小工具集# 综合运用函数定义、参数、返回值、if条件判断、字符串格式化# # ---------- 工具1温度转换 ----------defconvert_temp(value,unit): 温度转换函数 参数value - 温度数值unit - 原始单位C或F 返回转换后的温度保留1位小数和说明文字 ifunitC:# 摄氏 → 华氏F C * 9/5 32resultvalue*9/532returnround(result,1),f{value}°C {round(result,1)}°FelifunitF:# 华氏 → 摄氏C (F - 32) * 5/9result(value-32)*5/9returnround(result,1),f{value}°F {round(result,1)}°Celse:returnNone,f不支持的单位{unit}请输入 C 或 F# ---------- 工具2BMI计算 ----------defcalc_bmi(weight,height): BMI计算函数 参数weight - 体重(kg)height - 身高(m) 返回BMI值和健康等级 bmiweight/(height**2)bmiround(bmi,1)ifbmi18.5:level偏瘦elifbmi24:level正常elifbmi28:level偏胖else:level肥胖returnbmi,level# ---------- 工具3密码强度检测 ----------defcheck_password(password): 密码强度检测函数 参数password - 密码字符串 返回强度等级和改进建议 lengthlen(password)has_upperFalse# 是否有大写字母has_lowerFalse# 是否有小写字母has_digitFalse# 是否有数字forcharinpassword:ifchar.isupper():has_upperTrueelifchar.islower():has_lowerTrueelifchar.isdigit():has_digitTrue# 计算满足条件的个数score0iflength8:score1ifhas_upper:score1ifhas_lower:score1ifhas_digit:score1# 根据得分判断强度ifscore1:return弱,建议至少8位包含大小写字母和数字elifscore2:return中,建议增加密码长度加入更多字符类型elifscore3:return较强,建议再加入数字或大写字母会更安全else:return强,密码强度合格继续保持# ---------- 主程序调用三个工具 ----------print(*40)print( 实用小工具集 v1.0)print(*40)# 测试温度转换print(\n【温度转换】)temp_value,temp_msgconvert_temp(37,C)print(temp_msg)temp_value,temp_msgconvert_temp(100,F)print(temp_msg)# 测试BMI计算print(\n【BMI计算】)bmi_value,bmi_levelcalc_bmi(70,1.75)print(fBMI指数{bmi_value}{bmi_level})bmi_value,bmi_levelcalc_bmi(55,1.60)print(fBMI指数{bmi_value}{bmi_level})# 测试密码强度检测print(\n【密码强度检测】)pwd_list[123,abc12345,Abc12345,MyPass2024]forpwdinpwd_list:strength,advicecheck_password(pwd)print(f密码「{pwd}」→ 强度{strength}{advice})print(\n*40)print( 工具集演示完毕)print(*40)运行结果 实用小工具集 v1.0 【温度转换】 37°C 98.6°F 100°F 37.8°C 【BMI计算】 BMI指数22.9正常 BMI指数21.5正常 【密码强度检测】 密码「123」→ 强度弱建议至少8位包含大小写字母和数字 密码「abc12345」→ 强度中建议增加密码长度加入更多字符类型 密码「Abc12345」→ 强度较强建议再加入数字或大写字母会更安全 密码「MyPass2024」→ 强度强密码强度合格继续保持分步拆解工具1温度转换convert_temp(value, unit)接收两个参数温度数值和单位“C或F”用if-elif判断单位C走摄氏转华氏公式F走华氏转摄氏公式round(result, 1)保留1位小数返回两个值转换后的数值和格式化说明文字如果单位不合法返回None和错误提示工具2BMI计算calc_bmi(weight, height)接收体重和身高用公式体重 / 身高²计算用if-elif-else根据BMI值划分四个等级偏瘦、正常、偏胖、肥胖返回BMI数值和等级文字工具3密码强度检测check_password(password)接收密码字符串先用len()获取长度逐个字符检查.isupper()是否大写、.islower()是否小写、.isdigit()是否数字四个条件各计1分长度≥8、有大写、有小写、有数字满分4分根据得分返回强度等级和改进建议这三个函数都是输入参数 → 内部处理 →return返回结果的标准结构。你以后写的函数基本都是这个套路。注意convert_temp和calc_bmi都用了多返回值调用时用两个变量接收。十一、常见报错速查表报错信息出现场景原因解决方法NameError: name greet is not defined调用函数时函数定义写在调用之后或函数名拼写错误把 def 定义移到调用之前检查函数名拼写TypeError: greet() missing 1 required positional argument: name调用带参数的函数时函数需要参数但调用时没传补上参数greet(小明)TypeError: greet() takes 1 positional argument but 2 were given调用函数时函数只定义了1个参数调用时传了2个检查参数个数按定义的个数传TypeError: unsupported operand type(s) for : int and str函数内部运算时传入了错误类型的数据比如需要数字却传了字符串调用时做类型转换int(input(...))IndentationError: expected an indented block定义函数时def 冒号后没有缩进的代码块至少写一行缩进代码或写passSyntaxError: non-default argument follows default argument定义带默认值的参数时有默认值的参数放在了没有默认值的参数前面调整顺序普通参数在前默认参数在后十三、本章小结本章你掌握了 Python 函数的基础全套知识def 定义函数——def 函数名():把一段代码打包调用时写函数名加括号形参与实参——定义时写形参占位变量调用时传实参具体值按顺序一一对应return 返回值——把结果交还给调用处同时结束函数没写return则返回None多返回值——return a, b, c一次返回多个值调用时用对应数量的变量接收函数调用流程——主程序暂停→跳进函数执行→遇到return跳回主程序继续参数默认值——def fn(a, b10)让参数可选默认参数必须放在普通参数后面函数是编程中最重要的代码复用方式。以前你写 20 行代码只能用一次现在封装成函数一行调用就能复用。往期回顾《Python 零基础入门从积木到代码》专栏序零基础学 Python 第1章 | 全平台装环境 VS Code 配置 第一个 Hello World零基础学 Python 第2章 | print 输出 变量赋值 input 交互输入零基础学 Python 第3章 | 条件判断if / elif / else零基础学 Python 第 4 章 | for 循环与 range()让程序帮你重复干活零基础学 Python 第 5 章 | while 循环与循环嵌套让程序看着条件自己干活零基础学 Python 第 6 章 | 元组与集合不可变数据与自动去重零基础学 Python 第7章 | 字典 dict键值对存储零基础学 Python 第8章 | 字符串操作与格式化输出下一章预告本章的函数已经能用了但参数的玩法远不止于此。下一章学习函数进阶——默认参数的坑可变默认值问题、*args和**kwargs任意数量参数、变量作用域局部变量 vs 全局变量让你的函数更灵活更强大。文末资源区资源说明Python 官方文档 - 函数定义https://docs.python.org/3/tutorial/controlflow.html#defining-functionsPython 官方文档 - 函数参数https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functionsPython 官方文档 -return语句https://docs.python.org/3/reference/simple_stmts.html#the-return-statement本章完整源码chapter9_all.py关注梅雅达编程笔记评论领资料每节课都配套课后练习题与完整源码。代码报错、看不懂知识点可在评论区粘贴问题逐一解答欢迎关注梅雅达编程笔记持续分享Python零基础学习内容