PYTHON基础技能 – 使用Python进行异常处理的11个最佳实践

释放双眼,带上耳机,听听看~!

异常处理是编程中不可或缺的一部分,它能够帮助开发者优雅地处理程序运行过程中可能出现的各种错误,从而避免程序崩溃。Python 提供了丰富的异常处理机制,使得开发者可以更灵活地应对不同的异常情况。本文将详细介绍 Python 中异常处理的基本概念与高级用法,包括如何使用

1
try-except

结构、捕获特定异常、使用

1
finally

释放资源、抛出自定义异常、同时捕获多种异常、使用

1
else

块、使用

1
raise from

连接异常链、使用

1
assert

断言、使用上下文管理器以及使用日志记录异常等内容。

1. 理解异常机制

异常是程序运行过程中出现错误的一种信号。Python 中的异常处理机制可以帮助我们优雅地处理这些错误,避免程序崩溃。基本的异常处理结构是

1
try-except

代码示例:


1
try:<br>&nbsp;&nbsp;&nbsp;&nbsp;<em>#&nbsp;尝试执行可能出错的代码</em><br>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;10&nbsp;/&nbsp;0<br>except&nbsp;ZeroDivisionError:<br>&nbsp;&nbsp;&nbsp;&nbsp;<em>#&nbsp;处理除零错误</em><br>&nbsp;&nbsp;&nbsp;&nbsp;print("不能除以零!")

输出:


1
不能除以零!

解释:当尝试执行

1
10 / 0

时,程序会抛出

1
ZeroDivisionError

异常。通过

1
try-except

结构捕获并处理这个异常,避免了程序崩溃。

2. 捕获特定异常

不要笼统地使用

1
except:

来捕获所有异常,而应该具体指定哪些异常需要处理。这样可以让代码更具针对性和可维护性。

代码示例:


1
try:<br>&nbsp;&nbsp;&nbsp;&nbsp;num&nbsp;=&nbsp;int(input("请输入一个整数:"))<br>&nbsp;&nbsp;&nbsp;&nbsp;print(10&nbsp;/&nbsp;num)<br>except&nbsp;ValueError:<br>&nbsp;&nbsp;&nbsp;&nbsp;print("输入的不是整数!")<br>except&nbsp;ZeroDivisionError:<br>&nbsp;&nbsp;&nbsp;&nbsp;print("不能除以零!")

解释:这里分别处理了用户输入非整数和除零两种情况。这样可以明确地知道问题出在哪里,方便调试。

3. 使用
1
finally

释放资源

无论是否发生异常,

1
finally

块中的代码都会被执行。这通常用于清理或释放资源,如关闭文件或数据库连接等。

代码示例:


1
try:<br>&nbsp;&nbsp;&nbsp;&nbsp;file&nbsp;=&nbsp;open("example.txt",&nbsp;"r")<br>&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;file.read()<br>except&nbsp;FileNotFoundError:<br>&nbsp;&nbsp;&nbsp;&nbsp;print("文件不存在!")<br>finally:<br>&nbsp;&nbsp;&nbsp;&nbsp;file.close()&nbsp;&nbsp;<em>#&nbsp;即使前面有异常,也会关闭文件</em>

解释:即使在打开文件时遇到

1
FileNotFoundError

1
finally

块中的

1
file.close()

也会被执行,确保文件被正确关闭。

4. 抛出自定义异常

在某些情况下,预定义的异常类型可能不足以描述你的需求。这时可以自定义异常类,使异常信息更加明确。

代码示例:


1
class&nbsp;MyCustomException(Exception):<br>&nbsp;&nbsp;&nbsp;&nbsp;pass<br><br>def&nbsp;check_age(age):<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;age&nbsp;&lt;&nbsp;0:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;MyCustomException("年龄不能为负数!")<br><br>try:<br>&nbsp;&nbsp;&nbsp;&nbsp;age&nbsp;=&nbsp;-5<br>&nbsp;&nbsp;&nbsp;&nbsp;check_age(age)<br>except&nbsp;MyCustomException&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;print(e)

解释:自定义了一个异常

1
MyCustomException

,并在年龄小于零时抛出。这种方式可以使异常信息更加清晰。

5. 多个异常一起捕获

有时我们需要同时处理几种不同类型的异常。可以将多个异常类型放在一个元组中,一起捕获。

代码示例:


1
try:<br>&nbsp;&nbsp;&nbsp;&nbsp;age&nbsp;=&nbsp;input("请输入年龄:")<br>&nbsp;&nbsp;&nbsp;&nbsp;age&nbsp;=&nbsp;int(age)<br>&nbsp;&nbsp;&nbsp;&nbsp;print(10&nbsp;/&nbsp;age)<br>except&nbsp;(ValueError,&nbsp;ZeroDivisionError)&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"发生错误:{e}")

解释:这里捕获了

1
ValueError

1
ZeroDivisionError

两种异常。当输入不是整数或除数为零时,都能正确处理。

6. 使用
1
else

如果

1
try

块中的代码没有抛出任何异常,则可以执行

1
else

块中的代码。这通常用于处理正常情况下的逻辑。

代码示例:


1
try:<br>&nbsp;&nbsp;&nbsp;&nbsp;age&nbsp;=&nbsp;int(input("请输入年龄:"))<br>&nbsp;&nbsp;&nbsp;&nbsp;print(10&nbsp;/&nbsp;age)<br>except&nbsp;(ValueError,&nbsp;ZeroDivisionError)&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"发生错误:{e}")<br>else:<br>&nbsp;&nbsp;&nbsp;&nbsp;print("一切正常!")

解释:如果没有发生异常,就会执行

1
else

块中的代码。这里用来打印一条成功消息。

7. 使用
1
raise from

连接异常链

在处理异常时,有时候需要抛出一个新的异常,并保留原始异常的信息。Python 3 提供了

1
raise from

语法来实现这一点,帮助更好地追踪异常源头。

代码示例:


1
def&nbsp;read_file(filename):<br>&nbsp;&nbsp;&nbsp;&nbsp;try:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;open(filename,&nbsp;"r")&nbsp;as&nbsp;file:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;file.read()<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;FileNotFoundError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;ValueError("文件不存在!")&nbsp;from&nbsp;e<br><br>try:<br>&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;read_file("nonexistent.txt")<br>&nbsp;&nbsp;&nbsp;&nbsp;print(content)<br>except&nbsp;ValueError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"发生错误:{e}")

解释:

1
read_file

函数中,如果文件不存在,会抛出一个

1
FileNotFoundError

,然后在这个基础上抛出一个新的

1
ValueError

。通过

1
raise from

可以保留原始异常的信息。

输出:


1
发生错误:文件不存在!

完整异常信息:


1
ValueError:&nbsp;文件不存在!<br>&nbsp;&nbsp;from&nbsp;FileNotFoundError:&nbsp;&#091;Errno&nbsp;2]&nbsp;No&nbsp;such&nbsp;file&nbsp;or&nbsp;directory:&nbsp;'nonexistent.txt'

8. 使用
1
assert

断言

1
assert

语句可以在开发过程中检查条件是否为真。如果条件不满足,则抛出

1
AssertionError

。这对于调试非常有用。

代码示例:


1
def&nbsp;calculate_average(numbers):<br>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;len(numbers)&nbsp;&gt;&nbsp;0,&nbsp;"列表不能为空"<br>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;sum(numbers)&nbsp;/&nbsp;len(numbers)<br><br>try:<br>&nbsp;&nbsp;&nbsp;&nbsp;avg&nbsp;=&nbsp;calculate_average(&#091;])<br>&nbsp;&nbsp;&nbsp;&nbsp;print(avg)<br>except&nbsp;AssertionError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;print(f"断言失败:{e}")

解释:

1
calculate_average

函数中,使用

1
assert

检查列表是否为空。如果不为空,则计算平均值;否则抛出

1
AssertionError

输出:


1
断言失败:列表不能为空

9. 使用上下文管理器

Python 的上下文管理器(通过

1
with

语句)可以自动处理一些常见的资源管理任务,如文件操作。这可以简化异常处理代码。

代码示例:


1
with&nbsp;open("example.txt",&nbsp;"r")&nbsp;as&nbsp;file:<br>&nbsp;&nbsp;&nbsp;&nbsp;try:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;file.read()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(content)<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;Exception&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(f"读取文件时发生错误:{e}")

解释:使用

1
with

语句打开文件,并在

1
try

块中读取文件内容。即使在读取过程中发生异常,文件也会自动关闭。

10. 使用日志记录异常

在生产环境中,简单的错误提示可能不够。使用日志库(如

1
logging

)可以记录详细的异常信息,便于后续分析。

代码示例:


1
import&nbsp;logging<br><br>logging.basicConfig(level=logging.ERROR)<br><br>def&nbsp;divide(a,&nbsp;b):<br>&nbsp;&nbsp;&nbsp;&nbsp;try:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;/&nbsp;b<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;ZeroDivisionError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.error(f"除零错误:{e}")<br><br>result&nbsp;=&nbsp;divide(10,&nbsp;0)<br>print(result)

解释:使用

1
logging

库记录异常信息。当发生除零错误时,会记录详细的错误信息到日志文件或控制台。

输出:


1
ERROR:root:除零错误:division by zero<br>None

11. 实战案例:文件读写异常处理

假设我们要编写一个程序,从一个文件中读取数据,并将其写入另一个文件。在这个过程中,可能会遇到各种异常,如文件不存在、权限问题等。

代码示例:


1
import&nbsp;logging<br><br>logging.basicConfig(level=logging.ERROR)<br><br>def&nbsp;read_and_write_files(input_file,&nbsp;output_file):<br>&nbsp;&nbsp;&nbsp;&nbsp;try:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;open(input_file,&nbsp;"r")&nbsp;as&nbsp;in_file,&nbsp;open(output_file,&nbsp;"w")&nbsp;as&nbsp;out_file:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;in_file.read()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out_file.write(content)<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;FileNotFoundError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.error(f"文件不存在:{e}")<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;PermissionError&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.error(f"权限错误:{e}")<br>&nbsp;&nbsp;&nbsp;&nbsp;except&nbsp;Exception&nbsp;as&nbsp;e:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.error(f"未知错误:{e}")<br><br><em>#&nbsp;测试代码</em><br>read_and_write_files("input.txt",&nbsp;"output.txt")

解释:这段代码实现了从

1
input.txt

文件读取内容,并写入

1
output.txt

文件的功能。通过

1
with

语句确保文件在操作完成后自动关闭,并通过

1
try-except

结构捕获并记录各种异常信息。

输出:


1
ERROR:root:文件不存在:&#091;Errno 2] No such file or directory:&nbsp;'input.txt'

总结

本文详细介绍了 Python 中异常处理的基本概念和高级用法,包括

1
try-except

结构、捕获特定异常、使用

1
finally

释放资源、抛出自定义异常、同时捕获多种异常、使用

1
else

块、使用

1
raise from

连接异常链、使用

1
assert

断言、使用上下文管理器以及使用日志记录异常等内容。通过这些技术的应用,我们可以更好地管理和处理程序运行过程中可能出现的各种错误,提高程序的健壮性和可维护性。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

安全运维之道:发现、解决问题的有效闭环

2024-4-14 20:59:36

安全运维

稳定性建设 – 架构优化的关键策略

2025-2-11 17:15:56

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索