函数入门 —— 把代码打包复用
普通课约 60 分钟
本课导读
你其实早就是函数的老用户了:print()、len()、int()——每次带括号的调用都是在使用别人打包好的代码。今天你从用户变成作者:学会用 def 把自己的代码打包成零件,需要时一声令下随处复用。函数是"写脚本"和"做软件"之间的分水岭。
复制粘贴的尽头是函数
假设你的程序要在三个地方给不同的人打招呼,还要根据时间说早上好/晚上好。没有函数就得把同一段 if/else 复制三遍——需求一变(比如加个"中午好"),三处都要改,漏一处就是 bug。
函数的解法:逻辑只写一遍,起个名字,到处调用:
语法拆解:
def 函数名(参数):——def 是 define(定义),括号里的参数是留给调用者填的空- 缩进的部分是函数体:调用时才执行,定义时只是"注册"
greet("小雨")是调用:把"小雨"填进name这个空,函数体跑一遍
注意执行顺序:Python 读到 def 时只是记下"有这么个函数",真正执行发生在调用的那一刻。定义了不调用,什么也不会发生。
return:函数的"产出"
print 只是把结果喊出来,很多时候你需要函数把结果交回来,供后续计算使用——这就是 return:
return 和 print 的区别是本课最重要的坑,一张表说清:
| return | ||
|---|---|---|
| 做什么 | 把值显示在屏幕上 | 把值交回给调用处 |
| 之后 | 值就散了,没法再用 | 值能存进变量、参与计算 |
| 类比 | 把菜喊给全餐厅听 | 把菜端到点菜人桌上 |
试试把上面 return fahrenheit 改成 print(fahrenheit) 再运行——第一个 print 会打出 None("什么都没交回来"的官方说法),后面的比较直接报错。函数要产出,就用 return。
另外:return 一执行,函数立刻结束(像循环里的 break)——后面的代码不会再跑。
参数进阶:多个参数与默认值
- 参数可以有多个,逗号分隔,按顺序对号入座
sugar=0是默认参数:调用时不填就用默认值——"大多数人不加糖,加糖的自己说"- 调用时写
sugar=3叫按名字传参,参数一多时可读性好得多
还注意到一个技巧:第一个 return 执行了函数就结束,所以第二个 return 前不需要写 else——这种"提前返回"的写法很常见。
说明
函数里创建的变量(如 fahrenheit)是局部变量——只在函数内部存在,函数结束就消失,外面访问不到。这是好事:函数像一个独立的小车间,内部的临时物料不会弄乱外面的世界。现在知道这个现象即可,阶段 1 会正式讲作用域。
函数是怎么改变代码的
看一个"函数化改造"的前后对比。把上一课的手机号打码逻辑打包:
体会一下:逻辑一旦打包,复用是零成本的(循环里一行调用),修改是一处生效的(想改成显示后两位?只改函数体)。你写的函数越多,你的"个人工具箱"就越厚——下一课的项目里,函数就是主角。
✍️ 练习
练习 1:及格判定器
写函数 is_pass(score):60 分及以上返回 True,否则返回 False。用几个分数调用验证,再配合 if 打印"及格/不及格"。
✅ 参考答案
def is_pass(score):
return score >= 60
print(is_pass(72))
print(is_pass(59))
if is_pass(85):
print("85 分:及格")
比较表达式本身就是 True/False,直接 return 它——不必写 if score >= 60: return True else: return False 的四行版。
练习 2:购物结算
写函数 checkout(price, count, discount=1.0):返回 单价 × 数量 × 折扣。分别用"不打折"和"八折(0.8)"各调用一次并打印结果。
✅ 参考答案
def checkout(price, count, discount=1.0):
return price * count * discount
print(f"原价买 3 件:{checkout(50, 3)} 元")
print(f"八折买 3 件:{checkout(50, 3, discount=0.8)} 元")
默认参数 1.0 表示“不打折”——让常见情况零负担,特殊情况显式声明,是设计参数的良好品味。
练习 3:列表平均分函数(挑战)
写函数 average(scores):接收一个分数列表,返回平均分。要求函数内部用循环累加(复习),并处理一个边界:空列表返回 0(否则除以零会报错)。
💡 提示
函数第一行就检查:if len(scores) == 0: return 0——提前返回挡掉危险情况,正常逻辑安心往下写。
✅ 参考答案
def average(scores):
if len(scores) == 0:
return 0
total = 0
for s in scores:
total = total + s
return total / len(scores)
print(average([72, 88, 95]))
print(average([]))
“先挡边界、再写主逻辑”叫卫语句(guard clause),是写健壮函数的第一习惯——真实世界的数据总有意外,函数要替调用者兜住。
随堂测验
1. def double(n): return n * 2 —— 只写这两行运行,屏幕上会输出什么?
2. 函数用 print 而不是 return 输出结果,会导致什么问题?
3. def tea(kind, sugar=0) 中 sugar=0 的含义是?
4. 函数体里 return 语句执行之后,函数体内后面的代码会怎样?
5. def calc(): result = 99 —— 调用 calc() 之后在函数外面 print(result),会发生什么?
本课小结
def 名字(参数):定义,调用才执行;参数是留给调用者填的空- return 交回来,print 喊出来——要产出必须 return;return 即收工
- 默认参数让常见情况零负担;按名字传参更清晰
- 卫语句先挡边界;函数内变量是局部的,外面拿不到
- 函数 = 复用零成本 + 修改一处生效,你的个人工具箱从此开张
下一课,用整个阶段 0 学的全部本事做一个真正的项目:文案生成器——作品集第一件,来了。
划选正文任意文字可高亮、批注或加入复习卡
讨论
载入中…