前面几章我们已经把函数的骨架搭起来了。
你已经知道,函数可以定义,可以接收参数,可以有默认值,也知道作用域会让局部变量和全局变量看起来像两套世界。 但真正让很多人学函数时有点模糊的,反而是一个看起来最常见的词:
return
很多新手其实用过很多次 return, 却没有真正想明白一件事:
函数执行完,究竟把什么交回来了 为什么有时候能接到结果,有时候却是 Noneprint() 和 return 看起来都能看到结果,它们到底差在哪 函数一旦遇到 return,后面的代码又为什么不继续执行了
这一章,我们就把 return 彻底讲透。
不是只告诉你怎么写, 而是让你真正理解:
return 不是一个装饰性语法, 它是函数把结果交还给外部世界的出口。
如果前面几章让函数学会了接收输入, 那这一章,就是让函数真正学会交付结果。
一、先说结论:没有 return,很多函数其实只是自己在屋里说话
我们先看一个很常见的函数:
defadd(a, b): print(a + b)
调用:
add(3, 5)
输出:
8
很多人到这里会觉得,挺好啊,函数已经把加法结果算出来了。
表面上没错。 但你很快就会发现,这个函数其实只是把结果打印给你看了。 它并没有真正把结果交出来,交给外部程序继续使用。
比如你现在想把这个结果再乘以 10:
result = add(3, 5)print(result * 10)
这时候大概率就出问题了。
因为 add(3, 5) 这个函数并没有返回真正的数字 8。 它只是打印了 8。 函数本身交回来的结果,不是你想的那个数。
这就是 return 最核心的出发点:
函数不只是自己做完事,还要把结果正式交还出去。
二、print 和 return,真的不是一回事
这是整章最重要的一件事。
很多人学函数时,最容易把 print() 和 return 混在一起。 因为它们看起来都像是把结果弄出来了。
但它们的角色完全不同。
print() 是展示。 它负责把内容显示在屏幕上,给人看。
return 是返回。 它负责把结果交还给函数外部,给程序继续用。
这两者不是一类动作。
看一个对比例子。
第一种:
defadd(a, b): print(a + b)x = add(3, 5)print(x)
输出通常会是:
8None
很多人第一次看到这里会愣住。
为什么不是两个 8?
因为 print(a + b) 只是把 8 打印出来了。 但这个函数真正返回的值,并不是 8。 由于它没有写 return,所以默认返回的是 None
再看第二种:
defadd(a, b):return a + bx = add(3, 5)print(x)
输出:
8
这次就正常了。
因为函数真正把 a + b 的结果返回出来了。 所以变量 x 接到的,才是真正的 8。
所以你一定要牢牢记住:
能看到结果,不代表函数返回了结果。print() 负责显示,return 才负责交付。
三、什么是 return
你可以先用一句最直白的话理解:
return 就是函数执行结束前,把某个结果交出去。
比如:
defadd(a, b):return a + b
这里的意思不是 打印 a + b。 而是:
把 a + b 这个结果,作为函数执行后的产出,正式交还给外面。
外面接不接,都可以。 但函数已经明确做了这个交付动作。
比如:
result = add(10, 20)print(result)
这时候 result 才能接到 30。
所以以后你看到 return,脑子里可以自动翻译成:
函数把这个值送出去了
四、没有写 return,函数到底返回什么
这也是特别经典的一点。
很多人以为,不写 return 就等于函数没有返回值。 更准确一点说,应该是:
没有显式写 return,函数会默认返回 None
看例子:
defsay_hello(): print('你好')result = say_hello()print(result)
输出通常是:
你好None
为什么会有 None?
因为这个函数确实没有显式返回别的内容。 所以 Python 默认给了它一个返回结果:
None
你前面其实已经学过 None, 它大概就表示 没有实际结果、空结果。
所以现在你要建立一个特别重要的认识:
每个函数执行完,都会有返回结果。 只是有的函数返回的是你明确写出来的值, 有的函数如果你没写,就默认是 None
这也是为什么前面那个只有 print() 的函数,最后接到的不是你想要的数字。
五、None 不是报错,它只是一个明确的空结果
这一点顺手也要理一下。
很多新手一看到 None 就紧张, 以为程序坏了、函数没成功。
其实不是。
None 只是表示:
这个函数没有返回你想要的具体结果 或者说,它没有返回除空结果之外的别的东西
比如这种函数:
defshow_menu(): print('1. 登录') print('2. 注册') print('3. 退出')
它的任务本来就是展示菜单。 它根本不需要返回什么具体数据。
所以这种函数默认返回 None,很正常。
也就是说,None 不一定代表错误。 很多时候,它只是说明:
这个函数的职责就是做动作,不是产出结果。
这点你要慢慢分清。
六、什么时候函数应该 return,什么时候不一定要 return
这个判断特别实用。
如果函数的任务是:
计算 提取 转换 判断 整理 生成一个结果
那通常都很适合用 return
比如:
求和:
defadd(a, b):return a + b
判断及格:
defis_pass(score):return score >= 60
清洗文本:
defclean_text(text):return text.strip().lower()
这些函数,本质上都在产出结果。 所以返回值很重要。
但如果函数的任务更偏:
打印 展示 提醒 输出菜单 播放提示
那它不一定非得返回具体数据。
比如:
defshow_menu(): print('欢迎使用系统') print('1. 登录') print('2. 注册')
这种函数更像是在做一个动作,而不是制造一个结果。 所以有没有返回值,不是绝对死规定,要看它的职责。
不过从实际写程序的角度看, 一旦你希望这个函数的结果还能被别的代码接着用,那就应该优先考虑 return
七、return 最核心的价值,不是结束函数,而是把结果交出去
很多人学 return 时,只记住了一个现象:
函数一遇到 return,后面就不执行了。
这个现象当然是对的。 但如果你只记住这一层,其实会把 return 看浅了。
return 真正最重要的,不是 打断。 而是 交付。
比如:
defsquare(num):return num * num
这里最重要的,不是函数提前结束。 而是:
它把平方结果正式交出来了
如果只理解成 提前结束,那你会一直把 return 当成一个流程控制词。 而忽略它其实是函数输出能力的核心。
更准确的理解应该是:
return 在交付结果的同时,也结束了当前函数执行。
这两个动作是一起发生的。 但交付结果,才是它更本质的职责。
八、函数一旦执行到 return,会立刻结束
这一点也必须讲清楚。
看例子:
deftest(): print('第一句')return'结束了' print('第二句')
调用:
result = test()print(result)
输出:
第一句结束了
你会发现,第二句 根本没有机会执行。
因为函数执行到 return 的那一刻, 就已经把结果交回去了,当前函数也同步结束。
所以 return 后面的代码,在同一次函数执行里通常是走不到的。
这也是为什么很多人会说:
return 像函数的出口
一旦走到出口,人就出去了,后面房间里的东西自然不再继续看。
九、return 后面可以跟什么
当前阶段你先记住一个非常实用的结论:
几乎任何类型的数据都可以 return
比如返回数字:
defadd(a, b):return a + b
返回字符串:
defwelcome(name):returnf'欢迎{name}学习 Python'
返回布尔值:
defis_even(num):return num % 2 == 0
返回列表:
defget_names():return ['张三', '李四', '王五']
返回字典:
defget_user():return {'name': '张三', 'age': 18}
你会发现,return 并不挑食。 只要这个值是函数处理后的结果,它就可以返回。
这一点很重要。 因为它意味着函数不只是能算数。 它还可以生产文本、判断真假、整理结构化数据。
十、最常见的一个误区:把 return 和变量接收割裂开看
比如:
defadd(a, b):return a + b
很多人会机械地背这句。 但真正写程序时,反而不知道它到底有什么意义。
更完整地理解应该是:
函数内部 return 把结果交出去 函数外部用变量把结果接住 然后继续往下处理
比如:
defadd(a, b):return a + bresult = add(3, 5)print(result * 10)
这里真正重要的,不是 return 这一个词。 而是整个数据流动过程:
函数算出 8 返回出去result 接住 外面继续用它做乘法
这才是 return 的完整价值。
所以以后你不要把 return 看成一句孤立语法。 要把它放进整个函数调用链里去理解。
十一、一个特别典型的例子:判断成绩是否及格
比如我们写一个函数:
defis_pass(score):return score >= 60
调用:
print(is_pass(80))print(is_pass(45))
输出:
TrueFalse
很多新手到这里会觉得:
那我直接 print 结果不也行吗
比如写成:
defis_pass(score): print(score >= 60)
表面上也能看到 True 或 False。 但一旦你想把这个结果拿去做判断,就不一样了。
比如:
defis_pass(score):return score >= 60score = 75if is_pass(score): print('及格了')else: print('没及格')
这就很自然。
因为 is_pass(score) 真正返回了一个布尔值。 外面的 if 才能基于它做判断。
如果你只是 print 掉, 那外面的程序其实拿不到真正的判断结果。
这就是 return 和 print 的根本差异。
十二、return 让函数真正能参与“组合”
这一点特别关键。
程序一旦稍微复杂一点,不可能每个函数都孤零零地自己跑完就结束。 很多时候,函数之间是要互相配合的。
比如:
先清洗文本 再拆分字段 再转成字典 再保存进列表
这时候,每一步函数都需要把结果交给下一步。
比如:
defclean_text(text):return text.strip()defsplit_text(text):return text.split(',')text = ' 张三,18,北京 'cleaned = clean_text(text)parts = split_text(cleaned)print(parts)
输出:
['张三', '18', '北京']
你看,这就是函数组合。
如果 clean_text() 不 return, 后面 split_text() 就接不到干净文本。 整个流程就断掉了。
所以 return 不只是给一个函数自己收尾。 它是在让函数与函数之间能够接力。
这点一旦想通,你会突然觉得函数开始真正活起来了。
十三、一个特别像工具函数的例子:价格计算
比如写一个商品总价函数:
defget_total(price, count):return price * count
调用:
total = get_total(59.9, 3)print(f'总价是{total:.2f}元')
输出:
总价是179.70元
这里就特别能体现 return 的价值。
函数负责把总价算出来。 外面负责决定这个结果怎么展示。
你会发现,这样的分工特别清楚。
函数里不要把展示、打印、格式化全糊在一起。 先把结果 return 出来,外面想怎么处理都行。
这也是为什么很多时候,return 其实是在帮你做职责拆分。
十四、return 可以提前结束函数,这在判断里特别有用
比如你想写一个函数,判断一个数是不是正数:
defcheck_num(num):if num > 0:return'正数'return'不是正数'
调用:
print(check_num(5))print(check_num(-3))
输出:
正数不是正数
你会发现,return 很适合这种分支逻辑。
满足条件,就直接交结果并结束。 不满足,再走后面的返回。
再比如判断成绩等级:
defget_level(score):if score >= 90:return'优秀'if score >= 60:return'及格'return'不及格'
调用:
print(get_level(95))print(get_level(75))print(get_level(40))
输出:
优秀及格不及格
这种写法非常常见,也非常自然。
因为它特别符合一个思路:
一旦结果已经确定,就没必要再往后跑了 直接 return 掉最干脆
十五、return 后面什么都不写,也是一种写法
比如:
deftest(): print('开始执行')return print('这里不会执行')
调用:
test()
输出:
开始执行
这里的 return 虽然没有跟具体值, 但它仍然会结束函数。
而且它返回的本质上仍然是 None
所以你可以理解成:
return 不写值,也是在主动结束函数,只不过交出去的是空结果
这在一些需要提前退出函数的场景里会见到。 不过当前阶段你先知道有这种用法就够了。
十六、函数里可以有多个 return 吗
可以,而且很常见。
比如刚才的成绩等级判断就是多个 return
defget_level(score):if score >= 90:return'优秀'if score >= 60:return'及格'return'不及格'
你会发现,这类函数并不是每个 return 都会执行。 而是:
函数运行到哪个分支,就执行哪个 return,然后立刻结束
所以多个 return 并不冲突。 它们只是函数在不同情况下的不同出口。
只要逻辑清楚,这种写法往往很实用。
十七、一个很容易踩坑的点:写了 return,却没真正用起来
比如:
defadd(a, b):return a + badd(3, 5)
这当然不算错。 函数确实返回了结果。
但如果你后面既不接住它,也不打印它, 那这个返回值其实就白白交出来了。
所以更完整的写法通常是:
result = add(3, 5)print(result)
或者:
print(add(3, 5))
或者再进一步:
print(add(3, 5) * 10)
也就是说,return 只是负责把结果送出来。 你外面还得决定要不要接、怎么用。
这点别忽略。
十八、再看一个很典型的文本清洗函数
比如前面字符串章节做过类似的事:
defclean_text(text): text = text.strip() text = text.lower()return text
调用:
result = clean_text(' PYTHON ')print(result)
输出:
python
这个函数为什么写得顺?
因为它的职责特别明确:
输入一段文本 处理它 返回清洗后的结果
如果你把它改成只 print:
defclean_text(text): text = text.strip() text = text.lower() print(text)
那它就很难再和别的逻辑接起来了。
所以你会越来越发现:
return 让函数更像工具 print 让函数更像演示
这不是说 print 不重要。 而是说两者用途不同。
十九、很多时候,return 是在帮你减少副作用
前一章我们讲作用域时提到过一个问题:
函数如果老去修改全局变量,程序会越来越难追踪。
而 return 恰恰是一种更干净的方式。
比如不要这样:
score = 60defadd_score():global score score += 10
更推荐这样:
defadd_score(score):return score + 10score = 60score = add_score(score)print(score)
你会发现,第二种更清楚。
输入是什么 输出是什么 函数没有偷偷动外面的变量 数据流向一眼就看见了
这也是为什么很多时候,return 不只是传递结果, 它还在帮你把程序写得更透明。
二十、一个特别实用的判断方法:这个函数到底该 print 还是 return
以后你写函数时,可以先问自己一句:
这个函数的结果,是给人看,还是给程序继续用
如果只是给人看,比如显示菜单、打印提示、输出日志, 那 print() 很自然。
如果结果还要继续参与后面的计算、判断、拼接、保存, 那就应该优先考虑 return
比如:
显示菜单:
defshow_menu(): print('1. 登录') print('2. 注册')
求总价:
defget_total(price, count):return price * count
判断及格:
defis_pass(score):return score >= 60
清洗文本:
defclean_text(text):return text.strip()
这个判断方法非常实用。 能帮你少走很多弯路。
二十一、最容易犯的几个错
第一个错,拿 print 当 return 用。
这是最经典的坑。 你能看到结果,不代表函数真的返回了结果。
第二个错,写了 return,却忘了函数到这里会立刻结束。 导致把一些本来想执行的代码写在 return 后面。
第三个错,函数返回了结果,但外面完全没接、没用,结果白白丢掉。
第四个错,是函数职责混乱。 本来应该负责“算结果”的函数,里面既 print 又 return 一大堆,搞得用途很模糊。
第五个错,是不理解没写 return 时为什么得到 None。 其实这不是异常,而是默认返回规则。
二十二、这一章最该建立的,不是语法感,而是“结果流动感”
你以后看到一个函数,最好脑子里自动过一遍:
它接收了什么 它内部做了什么 它最后把什么交出来了
这一步特别重要。
因为从编程的角度看,函数不是一个孤立小盒子。 它是整个程序数据流里的一个处理节点。
参数把数据送进去 return 把结果送出来
一旦你开始用这种流动视角去看函数, 很多以前模糊的东西都会清楚很多。
二十三、练习题:这章一定要自己敲顺
下面这些小练习,建议你一定亲手写一遍。
1. 定义一个函数,返回两个数的和
defadd(a, b):return a + bresult = add(3, 5)print(result)
2. 定义一个函数,返回一个成绩是否及格
defis_pass(score):return score >= 60print(is_pass(80))print(is_pass(45))
3. 定义一个函数,接收字符串,返回去掉两边空格后的结果
defclean_text(text):return text.strip()print(clean_text(' hello python '))
4. 定义一个函数,返回长方形面积
defarea(length, width):return length * widthprint(area(5, 3))
5. 对比 print 版本和 return 版本的区别
defadd_print(a, b): print(a + b)defadd_return(a, b):return a + bx = add_print(3, 5)y = add_return(3, 5)print(x)print(y)
把这段跑一遍,你会对 print 和 return 的区别更有感觉。
6. 写一个函数,根据成绩返回等级
defget_level(score):if score >= 90:return'优秀'if score >= 60:return'及格'return'不及格'print(get_level(95))print(get_level(75))print(get_level(40))
这一题特别适合理解多个 return 的执行方式。
二十四、本章小结
这一章最重要的,不是记住 return 这个单词,而是把它的本质真正想清楚。
return 的作用,是把函数处理后的结果正式交还给外部。 它不是展示结果,而是返回结果。print() 负责给人看,return 负责给程序继续用。 函数一旦执行到 return,当前函数会立刻结束。 如果函数没有显式写 return,默认返回的是 None
更重要的是,你现在应该开始有一个更清晰的函数观:
参数负责输入 return 负责输出 函数就是一个接收输入、处理数据、交出结果的处理单元
这一步非常关键。 因为从这一章开始,你写函数时不再只是想着“把代码包起来”, 而是开始真正思考:
这个函数到底交付了什么结果
下一章我们继续讲 递归函数入门:函数为什么可以调用自己。 到那一章,你会见到函数世界里一个看起来最神奇、但其实逻辑很清楚的现象:
函数居然可以自己调用自己。