AI编程(十):错误处理 — 让程序不会”崩溃”

作者:

try/except,给程序装安全网

程序为什么”一碰就碎”?

上一篇我们给通讯录加上了文件保存功能,程序已经很好用了。但你有没有遇到过这种情况:

请输入选择:5
请输入年龄:abc
Traceback (most recent call last):
  File "通讯录.py", line 15, in 
    年龄 = int("abc")
ValueError: invalid literal for int() with base 10: 'abc'

程序直接崩溃了。红色的报错信息看得人一头雾水。

这就像一个不会游泳的人跳进了深水区——没有救生圈,直接沉底。

我们需要一个”安全网”: 即使出了意外,程序也不会崩溃,而是优雅地告诉你:”出了一点小问题,但我会继续运转。”

这就是”错误处理”——Python的 try/except 机制。

用”安全网”来理解 try/except

想象你是一个走钢丝的杂技演员。没有安全网的时候,摔一跤就完了。有了安全网,即使失足,也能落到网上,爬起来继续走。

钢丝表演 Python代码 含义

|—|—|—|

开始走钢丝 try: 把可能出错的代码放进来
失足摔下去 出错了 某行代码报错了
落到安全网上 except: 捕获错误,执行补救方案
继续表演 后面的代码 程序正常往下跑

最简单的写法:

try:
    有可能出错的代码
except:
    出错了怎么办

第一个 try/except

来看一个最简单的例子——用户输入数字:

try:
    年龄 = int(input("请输入你的年龄:"))
    print(f"你明年 {年龄 + 1} 岁")
except:
    print("⚠️ 你输入的不是数字哦!")

运行效果:

请输入你的年龄:abc
⚠️ 你输入的不是数字哦!

注意:没有红色报错,没有崩溃! 程序友好地告诉你出了问题,然后继续运行。

常见的错误类型

程序出错有各种各样的”姿势”。Python给每种错误都起了名字:

ValueError —— 值不对

# 把不是数字的字符串转成数字
年龄 = int("abc")    # ValueError: 不是合法的数字

TypeError —— 类型不对

# 字符串和数字不能直接相加
结果 = "年龄是" + 25    # TypeError: 字符串不能和数字相加

FileNotFoundError —— 文件不存在

# 打开一个不存在的文件
f = open("没有这个文件.txt")    # FileNotFoundError

ZeroDivisionError —— 除以零

# 数学上不能除以零
结果 = 100 / 0    # ZeroDivisionError

KeyError —— 字典里没有这个键

通讯录 = {"张三": "13800001111"}
电话 = 通讯录["李四"]    # KeyError: '李四'

IndexError —— 列表索引越界

成绩 = [90, 85, 78]
print(成绩[5])    # IndexError: 列表只有3个元素

分门别类捕获——多个 except

有时候 try 里面可能出不同的错,我们需要分别处理:

try:
    年龄 = int(input("请输入年龄:"))
    结果 = 100 / 年龄
    print(f"结果是 {结果}")
except ValueError:
    print("⚠️ 请输入数字,不是文字!")
except ZeroDivisionError:
    print("⚠️ 年龄不能是0!")
except:
    print("⚠️ 出了未知错误")

顺序很重要: 先写具体的错误类型,最后写 except:(兜底)。就像医院分诊——先去对应科室,实在不行才去急诊。

else 和 finally

try/except 还有两个小伙伴:

try:
    年龄 = int(input("请输入年龄:"))
except ValueError:
    print("输入有误!")
else:
    print(f"输入成功,你 {年龄} 岁")
finally:
    print("不管成功失败,我都会执行")
关键字 什么时候执行 类比

|—|—|—|

try 尝试执行 走钢丝
except 出错时执行 落到安全网上
else 没出错时执行 成功走完,观众鼓掌
finally 无论如何都执行 表演结束,收拾道具

finally 最常见的用途是:确保资源被释放。比如打开了文件,不管有没有出错,都要关掉它。

主动抛出错误——raise

有时候你需要”故意”引发一个错误,来提醒使用者:

def 设置年龄(年龄):
    if 年龄  150:
        raise ValueError("年龄不能超过150岁!")
    print(f"年龄设置为 {年龄}")

try:
    设置年龄(-5)
except ValueError as 错误:
    print(f"❌ {错误}")
# 输出:❌ 年龄不能是负数!

raise 就是你主动说:”这不对!”——然后交给 except 去处理。

实战:让通讯录程序”百毒不侵”

现在把学到的错误处理用到通讯录上。这个版本的通讯录,不管用户怎么乱输入,都不会崩溃:

import json

文件名 = "通讯录.json"

def 读取通讯录():
    try:
        with open(文件名, "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        return {}          # 文件不存在,返回空字典
    except json.JSONDecodeError:
        return {}          # 文件内容坏了,也返回空字典

def 保存通讯录(通讯录):
    with open(文件名, "w", encoding="utf-8") as f:
        json.dump(通讯录, f, ensure_ascii=False, indent=2)

通讯录 = 读取通讯录()

while True:
    print("n=== 通讯录 ===")
    print("1. 查看所有联系人")
    print("2. 添加联系人")
    print("3. 搜索联系人")
    print("4. 删除联系人")
    print("5. 退出")

    选择 = input("请输入选择(1-5):")

    if 选择 == "1":
        if not 通讯录:
            print("📭 通讯录为空")
        else:
            for 名字, 信息 in 通讯录.items():
                print(f"  {名字}:{信息['电话']}")

    elif 选择 == "2":
        名字 = input("姓名:").strip()
        if not 名字:
            print("⚠️ 姓名不能为空")
            continue
        电话 = input("电话:").strip()
        if not 电话:
            print("⚠️ 电话不能为空")
            continue
        通讯录[名字] = {"电话": 电话}
        保存通讯录(通讯录)
        print(f"✅ 已添加 {名字}")

    elif 选择 == "3":
        关键字 = input("输入要搜索的姓名:").strip()
        try:
            信息 = 通讯录[关键字]
            print(f"  {关键字}:{信息['电话']}")
        except KeyError:
            print(f"  ❌ 找不到「{关键字}」")

    elif 选择 == "4":
        名字 = input("要删除谁:").strip()
        try:
            del 通讯录[名字]
            保存通讯录(通讯录)
            print(f"✅ 已删除 {名字}")
        except KeyError:
            print(f"  ❌ 找不到「{名字}」")

    elif 选择 == "5":
        print("👋 再见!")
        break

    else:
        print("⚠️ 请输入 1-5 的数字")

这个版本做了哪些”防崩溃”处理?

用户可能的错误 处理方式

|—|—|

文件不存在 FileNotFoundError → 返回空字典
输入了 6、7、8 这种无效选项 else 提示”请输入1-5″
姓名/电话留空 strip() + if not 检查
搜索不存在的人 KeyError → 提示”找不到”
删除不存在的人 KeyError → 提示”找不到”

不管用户怎么乱来,程序都不会崩溃。 这就是一个”百毒不侵”的程序。

小结

概念 作用 安全网类比

|—|—|—|

try/except 捕获错误,防止崩溃 安全网接住掉落的人
多个 except 分别处理不同错误 不同科室看不同病
else 没出错时执行 成功表演后观众鼓掌
finally 无论如何都执行 散场后收拾舞台
raise 主动引发错误 发现问题主动叫停
常见错误类型 ValueErrorTypeErrorKeyErrorFileNotFoundError 各种”摔倒姿势”

核心原则: 对用户的输入永远不信任,对文件和外部资源永远做好”不存在”的准备。加几行 try/except,程序就从”玻璃心”变成”钢铁侠”。

下篇预告

《AI编程(十一):AI帮你选技术栈》

写了这么多程序,你有没有想过:Python能做网站吗?能做游戏吗?能做手机App吗?答案是——能,但每种需求都有最合适的技术栈。下一篇我们让AI帮你分析需求、推荐工具,从”会写代码”升级到”知道用什么写代码”。

下一篇:AI编程11-AI帮你选技术栈

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注