Python零基础教程第九课:犯错了怎么办?——错误处理

浏览量:20 次 发布时间:2025-12-26 20:23 作者:明扬工控商城 下载docx

最近更新:Python零基础教程第七课:我的第一个工具箱——函数


欢迎来到第九课。在编程的过程中,犯错是不可避免的。今天我们要学习如何处理错误,让程序即使遇到问题也能优雅地继续运行,而不是直接崩溃。就像我们走路可能会摔倒,但学会如何安全地摔倒和爬起来更重要。

第一部分 为什么需要错误处理?

想象一下,你写了一个除法计算器程序:

代码部分:
没有错误处理的除法计算器
print("除法计算器")
print("请输入两个数字进行除法计算")

数字1 = float(input("请输入第一个数字(被除数):"))
数字2 = float(input("请输入第二个数字(除数):"))

结果 = 数字1 / 数字2
print(f"{数字1} ÷ {数字2} = {结果}")

print("计算完成!")

这个程序看起来没问题,但如果用户输入了0作为除数,程序就会崩溃:
ZeroDivisionError: float division by zero

错误处理就是给程序穿上防弹衣,即使遇到问题也能继续运行。

第二部分 Python中的常见错误类型

在学会处理错误之前,我们先了解一下常见的错误类型:

1.    语法错误(SyntaxError)
语法错误就像写作文时写错字,程序根本不能运行。

代码部分:
语法错误示例
print("Hello World" 缺少右括号

if True
print("缺少冒号")

2.    名称错误(NameError)
使用了未定义的变量。

代码部分:
名称错误示例
print(未定义的变量) 变量还没定义就使用

3.    类型错误(TypeError)
操作或函数应用于不适当类型的对象。

代码部分:
类型错误示例
数字 = 123
结果 = 数字 + "abc" 数字和字符串不能直接相加

4.    值错误(ValueError)
函数接收到类型正确但值不合适的参数。

代码部分:
值错误示例
数字 = int("abc") "abc"不能转换为整数

5.    零除错误(ZeroDivisionError)
除数为零。

代码部分:
零除错误示例
结果 = 10 / 0 不能除以0

6.    索引错误(IndexError)
访问列表或字符串时索引超出范围。

代码部分:
索引错误示例
列表 = [1, 2, 3]
print(列表[5]) 列表只有3个元素,索引5不存在

7.    文件未找到错误(FileNotFoundError)
尝试打开不存在的文件。

代码部分:
文件未找到错误示例
with open("不存在的文件.txt", "r") as 文件:
内容 = 文件.read()

第三部分 try-except 捕获和处理错误

Python使用try-except语句来捕获和处理错误。

基本语法

代码部分:
try:
可能会出错的代码
except 错误类型:
处理错误的代码

简单的try-except例子

代码部分:
处理除零错误
try:
数字1 = 10
数字2 = 0
结果 = 数字1 / 数字2
print("结果是:", 结果)
except ZeroDivisionError:
print("错误:除数不能为零!")

print("程序继续运行...")

处理多种错误

代码部分:
处理多种错误
try:
数字 = int(input("请输入一个数字:"))
倒数 = 1 / 数字
print(f"{数字}的倒数是:{倒数}")
except ValueError:
print("错误:请输入有效的数字!")
except ZeroDivisionError:
print("错误:不能输入0!")
except Exception as e:
print(f"发生了未知错误:{e}")

print("程序结束")

第四部分 完整的错误处理结构

完整的错误处理结构包括:try、except、else和finally。

try-except-else-finally结构

代码部分:
完整的错误处理结构
def 安全除法(被除数, 除数):
try:
结果 = 被除数 / 除数
except ZeroDivisionError:
print("错误:除数不能为零!")
return None
except TypeError:
print("错误:请输入数字!")
return None
else:
如果没有发生错误,执行else部分
print("计算成功!")
return 结果
finally:
无论是否发生错误,都会执行finally部分
print("计算过程结束")

测试
print("测试1:正常计算")
print(安全除法(10, 2))

print("\n测试2:除零错误")
print(安全除法(10, 0))

print("\n测试3:类型错误")
print(安全除法(10, "abc"))

第五部分 else和finally的区别

else:当没有错误时执行

代码部分:
else的使用
try:
数字 = int(input("请输入一个数字:"))
except ValueError:
print("输入的不是数字!")
else:
只有在没有错误时才执行
print(f"你输入的数字是:{数字}")
print(f"它的平方是:{数字 ** 2}")

finally:无论是否出错都执行

代码部分:
finally的使用(常用于清理资源)
try:
文件 = open("测试.txt", "w")
文件.write("测试内容")
结果 = 10 / 0 这里会出错
except ZeroDivisionError:
print("发生了除零错误")
finally:
无论是否出错,都会执行
文件.close()
print("文件已关闭")

第六部分 获取错误信息

有时候我们需要知道具体的错误信息。

获取错误信息的方法

代码部分:
获取错误信息
try:
数字 = int("abc")
except ValueError as 错误信息:
print(f"发生了值错误:{错误信息}")
print(f"错误类型:{type(错误信息)}")

打印完整的错误堆栈

代码部分:
打印完整的错误堆栈
import traceback

def 函数A():
函数B()

def 函数B():
函数C()

def 函数C():
raise ValueError("这是测试错误")

try:
函数A()
except Exception as e:
print("发生错误:")
traceback.print_exc() 打印完整的错误堆栈

第七部分 主动抛出错误(raise)

有时候我们需要主动抛出错误,告诉调用者出现了问题。

使用raise抛出错误

代码部分:
主动抛出错误
def 检查年龄(年龄):
if 年龄 < 0:
raise ValueError("年龄不能为负数!")
elif 年龄 < 18:
raise ValueError("未成年人不能使用此功能!")
elif 年龄 > 120:
raise ValueError("年龄不现实!")
else:
return f"年龄验证通过:{年龄}岁"

测试
测试年龄 = [15, 25, -5, 150]

for 年龄 in 测试年龄:
try:
结果 = 检查年龄(年龄)
print(结果)
except ValueError as e:
print(f"错误:{e}")

自定义错误类型

代码部分:
自定义错误类型
class 我的错误(Exception):
自定义错误类型
pass

class 年龄太小错误(Exception):
def init(self, 年龄, 最小年龄):
self.年龄 = 年龄
self.最小年龄 = 最小年龄
super().init(f"年龄{年龄}太小,最小年龄为{最小年龄}")

使用自定义错误
def 验证年龄(年龄):
if 年龄 < 18:
raise 年龄太小错误(年龄, 18)
return True

try:
验证年龄(15)
except 年龄太小错误 as e:
print(f"自定义错误:{e}")
print(f"输入的年龄:{e.年龄}")
print(f"要求的最小年龄:{e.最小年龄}")

第八部分 小项目 安全计算器

让我们用错误处理知识制作一个安全的计算器。

第一步:创建新文件
新建文件,保存为"安全计算器.py"

第二步:基础版安全计算器

代码部分:
安全计算器 1.0

def 安全输入数字(提示):
安全获取用户输入的数字
while True:
输入 = input(提示)
try:
数字 = float(输入)
return 数字
except ValueError:
print("错误:请输入有效的数字!")

def 安全除法(被除数, 除数):
安全的除法运算
try:
return 被除数 / 除数
except ZeroDivisionError:
print("错误:除数不能为零!")
return None

def 主函数():
print("=" * 40)
print(" 安全计算器 1.0")
print("=" * 40)

text

复制

下载
获取输入


数字1 = 安全输入数字("请输入第一个数字:")
数字2 = 安全输入数字("请输入第二个数字:")
选择运算
print("\n请选择运算:")
print("1. 加法 (+)")
print("2. 减法 (-)")
print("3. 乘法 (*)")
print("4. 除法 (/)")
选择 = input("\n请输入选择 (1-4): ")
执行运算
try:
    if 选择 == "1":
        结果 = 数字1 + 数字2
        运算符 = "+"
    elif 选择 == "2":
        结果 = 数字1 - 数字2
        运算符 = "-"
    elif 选择 == "3":
        结果 = 数字1 * 数字2
        运算符 = "*"
    elif 选择 == "4":
        结果 = 安全除法(数字1, 数字2)
        运算符 = "/"
    else:
        raise ValueError("无效的选择")
    
    if 结果 is not None:
        print(f"\n计算结果:{数字1} {运算符} {数字2} = {结果}")
        
except ValueError as e:
    print(f"错误:{e}")
print("\n计算完成!")

if name == "main":
主函数()

第三步:增强版安全计算器

代码部分:
安全计算器 2.0

import math

class 计算器错误(Exception):
计算器相关错误的基类
pass

class 输入错误(计算器错误):
输入错误
pass

class 运算错误(计算器错误):
运算错误
pass

def 获取数字(提示):
获取用户输入的数字,支持表达式
while True:
try:
输入 = input(提示).strip()

text

复制

下载
        如果输入是空,返回None表示跳过


        if 输入 == "":
            return None
        
        尝试直接转换
        try:
            return float(输入)
        except ValueError:
            尝试计算表达式
            注意:eval有安全风险,这里仅用于演示
            实际应用中应该使用更安全的方法
            结果 = eval(输入, {"__builtins__": {}}, {"sqrt": math.sqrt, "pi": math.pi})
            return float(结果)
            
    except (ValueError, SyntaxError, NameError):
        print("错误:请输入有效的数字或表达式!")
    except ZeroDivisionError:
        print("错误:表达式中包含除零操作!")
    except Exception as e:
        print(f"错误:{e}")

def 获取运算符():
获取运算符
运算符列表 = ["+", "-", "*", "/", "%", "**", "sqrt"]

text

复制

下载
print("\n可用运算符:")


for i, 运算符 in enumerate(运算符列表):
    print(f"{i+1}. {运算符}")
while True:
    try:
        选择 = input("\n请选择运算符 (输入序号或符号): ")
        
        如果是数字,转换为运算符
        if 选择.isdigit():
            索引 = int(选择) - 1
            if 0 <= 索引 < len(运算符列表):
                return 运算符列表[索引]
            else:
                raise 输入错误("无效的选择序号")
        如果是运算符符号,直接返回
        elif 选择 in 运算符列表:
            return 选择
        else:
            raise 输入错误("无效的运算符")
            
    except 输入错误 as e:
        print(f"错误:{e}")

def 执行运算(数字1, 运算符, 数字2=None):
执行运算并处理错误
try:
if 运算符 == "+":
if 数字2 is None:
raise 运算错误("加法需要两个数字")
return 数字1 + 数字2
elif 运算符 == "-":
if 数字2 is None:
raise 运算错误("减法需要两个数字")
return 数字1 - 数字2
elif 运算符 == "*":
if 数字2 is None:
raise 运算错误("乘法需要两个数字")
return 数字1 * 数字2
elif 运算符 == "/":
if 数字2 is None:
raise 运算错误("除法需要两个数字")
if 数字2 == 0:
raise 运算错误("除数不能为零")
return 数字1 / 数字2
elif 运算符 == "%":
if 数字2 is None:
raise 运算错误("取模需要两个数字")
if 数字2 == 0:
raise 运算错误("取模运算的除数不能为零")
return 数字1 % 数字2
elif 运算符 == "**":
if 数字2 is None:
raise 运算错误("幂运算需要两个数字")
return 数字1 ** 数字2
elif 运算符 == "sqrt":
if 数字1 < 0:
raise 运算错误("不能对负数开平方根")
return math.sqrt(数字1)
else:
raise 运算错误(f"不支持的运算符:{运算符}")

text

复制

下载
except 运算错误 as e:


    print(f"运算错误:{e}")
    return None
except OverflowError:
    print("错误:计算结果太大!")
    return None
except Exception as e:
    print(f"未知错误:{e}")
    return None

def 显示历史(历史记录):
显示计算历史
if not 历史记录:
print("暂无计算历史")
return

text

复制

下载
print("\n" + "=" * 50)


print("计算历史:")
print("=" * 50)
for i, 记录 in enumerate(历史记录, 1):
    if 记录["运算符"] == "sqrt":
        print(f"{i}. sqrt({记录['数字1']}) = {记录['结果']}")
    else:
        print(f"{i}. {记录['数字1']} {记录['运算符']} {记录.get('数字2', '')} = {记录['结果']}")
print("=" * 50)

def 主函数():
历史记录 = []

text

复制

下载
print("=" * 50)


print("             安全计算器 2.0")
print("=" * 50)
print("说明:")
print("- 输入数字时可以直接输入表达式,如:3.14 * 2")
print("- 输入空行可以跳过第二个数字(用于sqrt运算)")
print("- 输入'历史'查看计算历史")
print("- 输入'退出'结束程序")
print("=" * 50)
while True:
    try:
        获取第一个数字
        数字1 = 获取数字("\n请输入第一个数字(或表达式):")
        if 数字1 is None:
            print("错误:第一个数字不能为空")
            continue
        
        获取运算符
        运算符 = 获取运算符()
        
        如果是sqrt,只需要一个数字
        if 运算符 == "sqrt":
            数字2 = None
        else:
            数字2 = 获取数字("请输入第二个数字(或表达式,输入空行取消):")
            if 数字2 is None:
                print("取消当前计算")
                continue
        
        执行计算
        结果 = 执行运算(数字1, 运算符, 数字2)
        
        if 结果 is not None:
            保存到历史
            历史记录.append({
                "数字1": 数字1,
                "运算符": 运算符,
                "数字2": 数字2,
                "结果": 结果
            })
            
            显示结果
            if 运算符 == "sqrt":
                print(f"\n结果:sqrt({数字1}) = {结果}")
            else:
                print(f"\n结果:{数字1} {运算符} {数字2} = {结果}")
        
        询问是否继续
        选择 = input("\n是否继续计算?(y/n/历史): ").lower()
        
        if 选择 == "历史":
            显示历史(历史记录)
        elif 选择 == "n":
            print("\n感谢使用安全计算器,再见!")
            break
        
    except KeyboardInterrupt:
        print("\n\n检测到中断,程序结束")
        break
    except Exception as e:
        print(f"程序错误:{e}")
        print("程序将重启...")

if name == "main":
try:
主函数()
except Exception as e:
print(f"程序崩溃:{e}")
print("请检查程序代码")

第九部分 调试技巧

除了错误处理,调试也是非常重要的技能。

使用print调试

代码部分:
使用print调试
def 复杂计算(数字):
print(f"[调试] 输入数字:{数字}")

text

复制

下载
if 数字 < 0:


    print(f"[调试] 数字为负数")
    return None
结果 = 数字 * 2
print(f"[调试] 计算结果:{结果}")
return 结果

复杂计算(5)
复杂计算(-3)

使用断言(assert)

代码部分:
使用断言
def 计算年龄组(年龄):
断言:年龄应该在合理范围内
assert 0 <= 年龄 <= 120, f"年龄{年龄}不在合理范围内"

text

复制

下载
if 年龄 < 18:


    return "未成年"
elif 年龄 < 60:
    return "成年"
else:
    return "老年"

测试
try:
print(计算年龄组(25))
print(计算年龄组(150)) 这会触发断言错误
except AssertionError as e:
print(f"断言错误:{e}")

第十部分 今天学到了什么

今天的内容非常实用,我们学会了:

1.    错误类型:认识常见的Python错误

2.    try-except:捕获和处理错误的基本方法

3.    完整结构:try-except-else-finally的完整使用

4.    获取错误信息:如何获取详细的错误信息

5.    主动抛出错误:使用raise主动抛出错误

6.    自定义错误:创建自己的错误类型

7.    实际应用:制作安全计算器

8.    调试技巧:基本的调试方法

第十一部分 练习任务

任务1:用户注册验证
编写用户注册验证程序:

·         验证用户名(长度、字符限制)

·         验证密码(长度、复杂度)

·         验证邮箱格
明扬工控商城

推荐阅读:

Python零基础教程第十一课 综合项目 智能聊天机器人

Python零基础教程第十课 认识新朋友 模块和包

Python零基础教程第九课:犯错了怎么办?——错误处理

Python零基础教程第八课:与文件对话

Python零基础教程第五课:重复的魔法——循环

Python零基础教程第七课:我的第一个工具箱——函数

Python零基础教程第九课:犯错了怎么办?——错误处理.docx

将本文的Word文档下载到电脑

推荐度:

下载

全部评论

请登录
产业新闻-明扬资讯网
科技资讯-明扬资讯网