1. 什么是异常?
异常(exception)就是程序运行时发生的错误,比如试图打开一个不存在的文件、除以零或者输入了非法数据。python 会抛出异常来告诉你“嘿,这里出问题了!”。如果不处理,程序会直接崩溃,打印一堆错误信息(就是 traceback)。
异常处理的核心是用代码“捕获”这些错误,防止程序崩掉,还能给用户友好的提示。
2. 常见的 python 异常类型
python 内置了很多异常类型,了解它们能帮你更好地处理问题。以下是一些常见的异常:
zerodivisionerror
:除以零时触发。filenotfounderror
:试图打开不存在的文件。valueerror
:函数接收到不合适的参数,比如把字符串传给int()
。typeerror
:类型错误,比如试图把字符串和整数相加。indexerror
:列表索引超出范围。keyerror
:访问字典中不存在的键。
这些异常都是 python 的内置类,继承自 exception
类。你可以在代码中捕获它们。
3. 基本的 try-except 结构
python 用 try-except
块来处理异常。基本思路是:把可能出错的代码放进 try
块,如果出错了,就跳到 except
块执行。
来看个简单的例子:
try: num = int(input("请输入一个数字: ")) result = 10 / num print(f"10 除以 {num} 等于 {result}") except: print("出错了!可能输入了非法数字或除以零。")
运行这段代码:
- 如果用户输入一个合法数字,比如
5
,程序会打印10 除以 5 等于 2.0
。 - 如果输入了非数字(比如
"abc"
)或0
,程序会跳到except
块,打印错误提示,而不会崩溃。
这个 except
是个“通吃”模式,捕获所有异常。但最好别这样用,因为你不知道具体出了啥问题。接下来我们改进它。
4. 捕获特定异常
与其捕获所有异常,不如只捕获你关心的特定异常类型。这样能更精准地处理问题。python 允许在 except
后指定异常类型。
改写上面的例子:
try: num = int(input("请输入一个数字: ")) result = 10 / num print(f"10 除以 {num} 等于 {result}") except valueerror: print("请输入一个合法的数字!") except zerodivisionerror: print("不能除以零!")
现在:
- 如果输入
"abc"
,会触发valueerror
,打印“请输入一个合法的数字!”。 - 如果输入
0
,会触发zerodivisionerror
,打印“不能除以零!”。 - 其他异常(比如
keyboardinterrupt
)不会被捕获,程序会照常报错。
你可以捕获多个异常,也可以把异常对象保存下来,查看具体错误信息:
try: num = int(input("请输入一个数字: ")) result = 10 / num except valueerror as e: print(f"输入错误: {e}") except zerodivisionerror as e: print(f"除零错误: {e}")
这里 as e
把异常对象存到变量 e
,可以打印更详细的错误信息。
5. 使用 else 和 finally
try-except
还有两个好用的伙伴:else
和 finally
。
else
:如果try
块没出错,就执行else
块。适合放那些依赖try
块成功的代码。finally
:不管try
块有没有出错,finally
块都会执行。常用来做清理工作,比如关闭文件。
来看个例子:
try: num = int(input("请输入一个数字: ")) result = 10 / num except valueerror: print("请输入合法数字!") except zerodivisionerror: print("不能除以零!") else: print(f"计算成功!结果是: {result}") finally: print("程序结束,清理完成!")
运行效果:
- 输入
5
:打印“计算成功!结果是: 2.0”和“程序结束,清理完成!”。 - 输入
"abc"
:打印“请输入合法数字!”和“程序结束,清理完成!”。 - 输入
0
:打印“不能除以零!”和“程序结束,清理完成!”。
finally
特别适合确保资源被正确释放,比如:
try: file = open("data.txt", "r") content = file.read() except filenotfounderror: print("文件没找到!") else: print(f"文件内容: {content}") finally: try: file.close() print("文件已关闭") except nameerror: print("文件从未打开,无需关闭")
这里 finally
确保文件被关闭,即使文件没找到(导致 file
未定义)也能安全处理。
6. 抛出异常
有时候你想主动抛出异常,比如检查到用户输入不符合要求。可以用 raise
关键字抛出异常。
例子:
def divide(a, b): if b == 0: raise zerodivisionerror("除数不能为零!") return a / b try: result = divide(10, 0) except zerodivisionerror as e: print(f"错误: {e}")
运行会打印“错误: 除数不能为零!”。你可以用 raise
抛出任何内置异常,或者直接用 raise exception("自定义消息")
。
还可以“重新抛出”异常:
try: num = int(input("请输入一个数字: ")) except valueerror as e: print(f"输入错误: {e}") raise # 重新抛出原异常
这样会在处理完错误后,继续把异常抛给上层调用者。
7. 自定义异常
当内置异常不够用时,你可以定义自己的异常类。自定义异常通常继承自 exception
类。
例子:
class customvalueerror(exception): """自定义异常,用于值不符合要求""" pass def check_age(age): if age < 0 or age > 150: raise customvalueerror("年龄必须在0到150之间!") return age try: age = check_age(200) except customvalueerror as e: print(f"错误: {e}")
运行会打印“错误: 年龄必须在0到150之间!”。自定义异常让代码更清晰,尤其在复杂项目中。
8. 错误处理的最佳实践
最后,分享一些写错误处理代码的建议:
- 捕获特定异常:别用“通吃”的
except
,尽量指定具体的异常类型。 - 提供清晰的错误信息:用户看到错误时,应该知道问题出在哪,怎么解决。
- 用 else 和 finally 合理组织代码:
else
放依赖try
成功的逻辑,finally
放清理工作。 - 别滥用异常:异常是用来处理“异常情况”的,别用它来控制正常流程(比如代替
if
判断)。 - 记录错误日志:在实际项目中,用
logging
模块记录异常,方便调试。
例子(带日志):
import logging logging.basicconfig(level=logging.error, filename="app.log") try: num = int(input("请输入一个数字: ")) result = 10 / num except valueerror as e: logging.error(f"输入错误: {e}") print("请输入合法数字!") except zerodivisionerror as e: logging.error(f"除零错误: {e}") print("不能除以零!") else: print(f"结果: {result}") finally: print("程序结束!")
这个例子会把错误记录到 app.log
文件,方便排查问题。
到此这篇关于python 错误处理详解的文章就介绍到这了,更多相关python 错误处理详解内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论