《前端的 Python 入门指南》系列文章:
- (一):常用语法和关键字对比
- (二):函数的定义、参数、作用域对比
- (三):数据类型对比 - 彻底的一切皆对象实现和包装对象异同
- (四):参数传递方式对比 - 值与引用传递 vs 可变不可变数据
- (五):面向对象特性之继承实现的方式对比 - 基于原型链和基于类各有什么优缺点
- (六):调试方式和技巧对比
- (七):异步场景的实现方案对比 - 内置+显示事件循环 + async+await
- (八):多线程编程与实现方法对比
- (九):模块化的实现、使用及注意事项对比
- (十):常用的全局变量和接口介绍
在编程中,错误和异常是不可避免的。无论是语法错误、运行时错误,还是逻辑错误,都可能在程序的执行过程中出现。如何有效地处理这些错误,是每个开发者必须掌握的技能。特别是在 Python 中,异常处理的机制与JavaScript有所不同,理解其工作原理和最佳实践,能够帮助你编写更健壮和易维护的代码。
在本文中,我们将深入探讨 Python 中的错误和异常处理机制,并通过对比 Python 和 JavaScript 中的异常处理方式,帮助大家更好地理解 Python 异常处理的策略和最佳实践。
另外写给前端的python入门暂时完结,我将继续写《写给pythonier的前端进阶指南》,因为关注的python用户多一些,掌握多一点,能够做更有趣的事情。尤其python做后端+js做前端是很不错的,当学好了前端就可以做出炫酷的页面、让更多业务跑在前端,或者合适的时机使用合适的方案而不是一把梭哈后患无穷
稍微推荐下最新文章: GRU实战教程 - 文本情感分析之有害内容检测
一、什么是错误与异常?
- 错误(Error):通常指的是在程序运行过程中,导致程序无法继续执行的情况,常常是由编译错误、语法错误等引起的。
- 异常(Exception):是程序运行过程中出现的意外情况,但与错误不同,异常通常不会立刻导致程序崩溃。它可以被捕获和处理,从而避免程序中断。
Python 提供了完善的异常处理机制,允许程序在发生异常时进行自定义处理。通过异常处理机制,开发者可以有效地管理程序中的错误和异常,使程序更加健壮。
实际上编程中有两种学派:一种是已知错误不算错误派;一种是错误即错误派。前者会采用如下的行为:例如传入的参数不合法,不会抛出错误,而是一个包含success(类似的)+ error 的组合对象,让上层处理。后者会直接抛出错误。各有优缺点,其实错误最大的缺点可能是会影响性能,但我个人是站队后者的,因为可阅读性和一致性往往比那一丢丢的性能好。
二、Python 中的异常处理机制
在 Python 中,异常是通过 try
、except
、else
和 finally
语句来处理的。其基本结构如下:
try:# 可能引发异常的代码pass
except ExceptionType as e:# 异常处理代码pass
else:# 如果没有异常发生,则执行的代码pass
finally:# 无论是否发生异常,都会执行的代码pass
在js中,没有else , except则是catch。js中异常会导致中断,所以后续代码可以写在一个try里面
2.1 try
块
try
块中的代码是可能引发异常的代码。如果在 try
块中发生异常,Python 会跳过后续的代码并转到 except
块。
2.2 except
块
except
块用于捕获并处理异常。你可以捕获特定类型的异常,也可以捕获所有异常。捕获到异常后,你可以进行相应的处理,或是打印错误信息,甚至重新抛出异常。
try:x = 1 / 0
except ZeroDivisionError:print("Cannot divide by zero!")
2.3 else
块
else
块是可选的,只有在 try
块中的代码没有引发任何异常时,else
块中的代码才会执行。
try:x = 10
except ZeroDivisionError:print("Error")
else:print("No error occurred!")
2.4 finally
块
finally
块用于定义无论是否发生异常都需要执行的代码,通常用于释放资源或清理操作。finally
块中的代码总会执行,即使在 try
或 except
块中有 return
语句。
try:x = 10 / 2
finally:print("This will always execute.")
三、Python 异常类层次结构
Python 中的异常是一个类层次结构,所有异常类都继承自基类 BaseException
。其中最常用的异常类包括:
Exception
:所有标准异常的基类,通常用于捕获常见的异常类型。ValueError
:表示传入函数的参数类型正确,但值不合适时抛出的异常。TypeError
:表示类型不匹配时抛出的异常。IndexError
:表示索引超出范围时抛出的异常。KeyError
:表示字典查找键时发生的异常。FileNotFoundError
:表示文件未找到时抛出的异常。
try:x = int("string")
except ValueError as e:print(f"Caught ValueError: {e}")
这里有点模式匹配的味道,js则是全无类型。是throw后面的值,有时候甚至只是一个错误字符串而不是错误对象,我个人也经常直接抛出字符串 — 因为不用捕获堆栈,心理认为对性能影响小,而且起到中断的作用
四、Python 异常处理的最佳实践
4.1 捕获特定异常
尽量避免使用 except Exception:
来捕获所有异常,因为它会捕获所有类型的异常,包括系统异常和程序内部的错误。更好的做法是捕获特定的异常类型,这样可以对不同类型的异常做出相应的处理。
try:x = int("string")
except ValueError as e:print(f"ValueError occurred: {e}")
except TypeError as e:print(f"TypeError occurred: {e}")
4.2 避免空的 except
块
不要使用空的 except
块,这样会吞掉所有的异常,使得调试变得困难。至少要记录异常信息或者在 except
块中添加处理逻辑。
try:x = int("string")
except ValueError as e:print(f"An error occurred: {e}")# 可以选择记录错误日志
4.3 使用 else
和 finally
else
和 finally
使代码更加清晰和健壮。特别是在涉及资源管理时,finally
可以帮助我们确保资源的释放。
try:file = open("file.txt", "r")data = file.read()
except FileNotFoundError as e:print(f"File not found: {e}")
else:print("File read successfully")
finally:file.close() # 无论是否发生异常,都关闭文件
4.4 使用自定义异常
对于复杂的业务逻辑,往往需要定义自己的异常类型。Python 允许你通过继承 Exception
类来创建自定义异常类。这样可以更明确地表示特定的错误类型,并提供更具体的错误信息。
class CustomError(Exception):def __init__(self, message):self.message = messagesuper().__init__(self.message)try:raise CustomError("Something went wrong!")
except CustomError as e:print(f"Caught custom error: {e}")
4.5 异常链
有时,我们希望在处理异常时,能够保留原始异常的信息,Python 提供了异常链(Exception Chaining)机制,可以通过 from
关键字将原始异常与新异常关联。
try:x = 1 / 0
except ZeroDivisionError as e:raise ValueError("Custom error occurred") from e
这种机制能够提供更清晰的错误堆栈信息,帮助调试人员理解错误的发生过程。
五、与 JavaScript 异常处理的对比
JavaScript 和 Python 都支持异常处理,但它们的语法和处理方式有所不同。以下是两者的对比:
特性 | Python | JavaScript |
---|---|---|
基本结构 | try / except / else / finally | try / catch / finally |
异常类型 | 异常是类,Exception 是基类,支持自定义异常 | 异常是对象,Error 是基类,支持自定义错误 |
捕获所有异常 | 使用 except Exception: 来捕获所有异常 | 使用 catch (error) 来捕获所有异常 |
异常链 | raise ... from 语法支持异常链 | throw new Error("message") 不支持链式异常 |
资源清理 | finally 块确保资源清理 | finally 块确保资源清理 |
JavaScript 示例:
try {let x = 1 / 0;
} catch (e) {console.error("Caught an error:", e);
} finally {console.log("This will always execute.");
}
Python 示例:
try:x = 1 / 0
except ZeroDivisionError as e:print(f"Caught an error: {e}")
finally:print("This will always execute.")
六、总结
异常处理是编程中非常重要的一部分,它帮助我们捕捉和处理意外情况,从而避免程序崩溃。Python 提供了灵活且强大的异常处理机制,通过合理使用 try
、except
、else
和 finally
块,能够使代码更加健壮、易于维护。
在处理异常时,应该尽量捕获特定的异常类型,避免使用空的 except
块,必要时创建自定义异常类,并合理利用 finally
进行资源清理。通过这些最佳实践,你可以编写出更加稳定和可靠的 Python 程序。
系列终于结束了,其实在某个阅读不到1000时候我就打算放弃的,毕竟虽然不是100%原创,但一边写一边学习也是好的。后续我还是希望能够生动一点,不这么死板,但那得是技术熟练之后。
相信看完这个系列的十一篇章,阅读python代码肯定不成问题,修改下也可以。具体的实战后续我会出一些