一文彻底搞定 Python 的 Exception 处理

avatar
作者
筋斗云
阅读量:0

highlight: gruvbox-dark
theme: cyanosis

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益:

  1. 了解大厂经验
  2. 拥有和大厂相匹配的技术等

希望看什么,评论或者私信告诉我!

一、前言

最近代码中也经常看到类似

if file_type in ['doc', 'docx']:     file_extension='docx' elif file_type in ['sheet','sheets']:     file_type='sheet'     file_extension='xlsx' else:     raise ValueError("file_type not in ['doc', 'docx','xlsx']") 

异常处理的代码,写惯了 Java 的友友就会不禁好奇,为啥是 Error 而不是 Exception。Python 中 Error、Exception 跟 Java 中的还真不一样。

二、Exception

2.1 Exception 定义

异常(Exception)是指在程序执行期间出现的一些意外或异常情况,导致程序无法按照正常流程执行。异常通常是由于代码逻辑错误、外部环境变化等原因引起的,例如除零错误、文件不存在等。在 Python 中,异常被称为 “Exception”。xxxError 也是 Exception 的一种。比如:ValueError 就是 Exception 的子类

2.2 应用场景:

  • 异常通常是由于意外或异常情况引起的,因此在代码中应该使用异常处理机制来捕获和处理异常,以保证程序的健壮性和稳定性。异常处理可以包括对异常的捕获、记录、报告、恢复或其他适当的操作。
    当您编写代码时,应该使用异常处理来处理可能出现的异常情况。以下是一些常见的情况,其中使用异常处理是很常见的:
  1. 文件操作:在读取或写入文件时,可能会出现文件不存在、权限不足或文件格式错误等异常情况。使用异常处理可以捕获这些异常并采取适当的措施。
try:     file = open("myfile.txt", "r")     # 进行文件读取操作 except FileNotFoundError:     print("文件不存在") except PermissionError:     print("权限不足") except IOError:     print("读取文件时发生错误") finally:     file.close()  # 无论是否发生异常,都会执行文件关闭操作 
  1. 网络请求:在进行网络请求时,可能会遇到连接超时、请求错误或服务器返回错误状态码等异常情况。使用异常处理可以捕获这些异常并进行相应的处理。
import requests  try:     response = requests.get("https://api.example.com")     response.raise_for_status()  # 检查响应状态码,如果不是 200,则引发异常     # 处理响应数据 except requests.Timeout:     print("请求超时") except requests.HTTPError as e:     print("HTTP 错误:", e) except requests.RequestException:     print("请求发生错误") 
  1. 数据验证:在处理用户输入或外部数据时,需要验证数据的有效性。如果数据不符合预期,可以引发相应的异常。
def process_data(data):     if not isinstance(data, list):         raise TypeError("数据应该是一个列表")     # 处理数据  try:     input_data = get_user_input()     process_data(input_data) except TypeError as e:     print("数据处理错误:", e) 

这些示例只是一小部分常见的情况,使用异常处理可以帮助您处理不同类型的异常情况,提供错误信息,并采取适当的措施来处理异常。通过使用异常处理,您可以使程序更加健壮,并提供更好的用户体验,而不会导致程序崩溃或产生不可预料的结果。

2.3 异常的使用

2.3.1 抛出异常 Raise Exception

  • 使用 raise 语句可以显式地抛出异常。可以抛出内置的异常类,如 ValueErrorTypeError,或自定义的异常类。
  • 抛出异常的语法是 raise ExceptionType("错误消息")。可以提供一个字符串作为错误消息,以便更好地描述异常情况。
def divide_numbers(num1, num2):     if num2 == 0:         raise ZeroDivisionError("Division by zero")     return num1 / num2   result = divide_numbers(10, 0)  print("结果:", result) 

当 num2=0 时,也就是除数为 0 时,抛出异常 ZeroDivisionError。

2.3.2 捕获异常(Catch Exception)

  • 使用 try-except 语句可以捕获并处理异常。try 块中的代码用于监视可能引发异常的操作。
  • 如果在 try 块中引发了异常,控制权将转移到与异常匹配的 except 块,该块用于处理该异常。
  • 可以使用多个 except 块来捕获不同类型的异常,以便为不同的异常提供特定的处理逻辑。
  • 可以使用单个 except 块来捕获多个异常类型,或者使用通用的 Exception 类来捕获所有异常。
import requests  try:     response = requests.get("https://api.example.com")     response.raise_for_status()  # 检查响应状态码,如果不是 200,则引发异常     # 处理响应数据 except requests.Timeout:     print("请求超时") except requests.HTTPError as e:     print("HTTP 错误:", e) except requests.RequestException:     print("请求发生错误") 

2.3.3 finally 块

  • 可以使用 finally 块来定义无论是否发生异常都会执行的代码块。无论异常是否被捕获或处理,finally 块中的代码都将执行。
  • finally 块通常用于执行清理操作,如关闭文件或释放资源。
try:     num1 = int(input("请输入一个整数: "))     num2 = int(input("请输入另一个整数: "))       # 可能引发异常的代码块     result = num1 / num2     print("结果:", result) except ValueError:     print("输入的不是有效的整数") except ZeroDivisionError:     print("除数不能为零") else:     print("没有发生异常") finally:     print("异常处理结束")  # 示例输入:5、0 

三、自定义异常

鼓励程序员从 Exception类或它的某个子类来派生新的异常,比如:

class MyCustomException(Exception):     def __init__(self, message, error_code):         super().__init__(message)         self.error_code = error_code 

在这个示例中,MyCustomException 类具有一个构造函数,接受 message 和 error_code 参数,并调用父类 Exception 的构造函数。此外,它还定义了一个 log_error 方法,用于记录错误信息。
自定义异常使用:

try:     raise MyCustomException("Something went wrong", 500) except MyCustomException as e:     print("Caught custom exception:", e) 

总结

Python中的异常处理机制能够有效地捕获和处理程序执行过程中的异常情况,确保程序的健壮性和稳定性。文章全面介绍了异常的基本概念、使用方式和自定义异常的方法,对于Python开发者来说是很好的参考资料。

下面这张关系图来自 Built-in Exceptions — Python 3.12.2 documentation

BaseException  ├── BaseExceptionGroup  ├── GeneratorExit  ├── KeyboardInterrupt  ├── SystemExit  └── Exception       ├── ArithmeticError       │    ├── FloatingPointError       │    ├── OverflowError       │    └── ZeroDivisionError       ├── AssertionError       ├── AttributeError       ├── BufferError       ├── EOFError       ├── ExceptionGroup [BaseExceptionGroup]       ├── ImportError       │    └── ModuleNotFoundError       ├── LookupError       │    ├── IndexError       │    └── KeyError       ├── MemoryError       ├── NameError       │    └── UnboundLocalError       ├── OSError       │    ├── BlockingIOError       │    ├── ChildProcessError       │    ├── ConnectionError       │    │    ├── BrokenPipeError       │    │    ├── ConnectionAbortedError       │    │    ├── ConnectionRefusedError       │    │    └── ConnectionResetError       │    ├── FileExistsError       │    ├── FileNotFoundError       │    ├── InterruptedError       │    ├── IsADirectoryError       │    ├── NotADirectoryError       │    ├── PermissionError       │    ├── ProcessLookupError       │    └── TimeoutError       ├── ReferenceError       ├── RuntimeError       │    ├── NotImplementedError       │    └── RecursionError       ├── StopAsyncIteration       ├── StopIteration       ├── SyntaxError       │    └── IndentationError       │         └── TabError       ├── SystemError       ├── TypeError       ├── ValueError       │    └── UnicodeError       │         ├── UnicodeDecodeError       │         ├── UnicodeEncodeError       │         └── UnicodeTranslateError       └── Warning            ├── BytesWarning            ├── DeprecationWarning            ├── EncodingWarning            ├── FutureWarning            ├── ImportWarning            ├── PendingDeprecationWarning            ├── ResourceWarning            ├── RuntimeWarning            ├── SyntaxWarning            ├── UnicodeWarning            └── UserWarning 

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!