python基础篇(8):异常处理

发布于:2024-07-08 ⋅ 阅读:(36) ⋅ 点赞:(0)

在Python编程中,异常是程序运行时发生的错误,它会中断程序的正常执行流程。异常处理机制使得程序能够捕获这些错误,并进行适当的处理,从而避免程序崩溃。

1 错误类型

代码的错误一般会有语法错误和异常错误两种,语法错误就是代码没有按照 Python 规定语法去写导致程序无法执行,比如代码的格式、缩进等。另外一种是异常错误,即使语法正确,程序在运行过程中也可能会出错,比如用户输入了错误的内容,列表的索引不存在,字典的key不存在等等。

使用异常处理可以在异常错误的时候,执行特定的逻辑,让程序可以继续执行,如果不对异常捕获,程序将终止执行。

异常的分类

(1)内置异常类

  • zeroDivisionError:除(或取模)零
  • IndexError:序列中没有此索引(index)
  • KeyError:映射中没有这个键
  • SyntaxError:Python 语法错误
  • OSError:操作系统异常(如:文件打开异常)
  • keyboardInterrupt:键盘中断错误,Ctrl+c使得程序异常退出
  • RuntimeError:运行时错误
  • Exception:所有异常的父类

(2)自定义异常类

可以通过自定义类,继承 Exception 实现。

2 捕获异常

2.1 捕获常规异常

try:
    可能发生错误的代码
except:
    如果出现异常执行的代码

示例如下:

需求:尝试以`r`模式打开文件,如果文件不存在,则以`w`方式打开。

try:
    f = open('linux.txt', 'r')
except:
    f = open('linux.txt', 'w')

2.2 捕获指定异常

try:
    print(name)
except NameError as e:
    print('name变量名称未定义错误')

注意事项:

  • 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
  • 一般try下方只放一行尝试执行的代码。

2.3 捕获多个异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。

try:
    print(1/0)
except (NameError, ZeroDivisionError) as e:
    print(e)

结果如下:

也可以使用带有分支的异常处理,如下:

try:
    # 可能会引发异常的代码
    print(1/0)
except ValueError as ve:
    # 处理ValueError的代码
    print(f"ValueError occurred: {ve}")
except ZeroDivisionError as ze:
    # 处理ValueError的代码
    print(f"ZeroDivisionError occurred: {ze}")
except TypeError as te:
    # 处理TypeError的代码
    print(f"TypeError occurred: {te}")
except Exception as e:
    # 处理其他所有类型的异常
    print(f"An error occurred: {e}")

结果如下:

2.4 捕获所有异常

try:
    print(name)
except Exception as e:
    print(e)

结果如下:

2.5 捕获else分支

还可以使用 else 和 finally 子句。

  • else:当try块中的代码没有引发异常时,执行else块的代码。
  • finally:无论是否发生异常,finally块的代码总会执行。
try:
    f = open('test.txt', 'r')
except Exception as e:
    f = open('test.txt', 'w')
else:
    print('没有异常,真开心')
finally:
    f.close()

3 抛出异常

在Python中,可以使用 raise 关键字手动抛出异常。

def divide(x, y):
    if y == 0:
        raise ValueError("y cannot be zero")
    return x / y

divide(4, 2)
divide(3, 0)

结果如下:

可以在函数或代码块中根据需要抛出特定类型的异常,以便在其他地方进行捕获和处理。

4 自定义异常

有时标准异常不足以描述特定的错误情况,可以通过创建自定义异常类来定义新的异常类型

class CustomError(Exception):
    """自定义异常类"""
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return f"CustomError: {self.message}"

# 使用自定义异常
try:
    raise CustomError("This is a custom error")
except CustomError as ce:
    print(ce)

结果如下:

5 异常传递

当一个异常在函数中未被处理时,该异常会向上传递到调用该函数的地方,直到被捕获或到达程序的顶层,从而导致程序崩溃。

  • read_file函数试图打开一个文件,如果文件不存在,会捕获FileNotFoundError并抛出一个自定义的CustomError。
  • process_file函数调用read_file并尝试处理文件内容,如果发生CustomError,会捕获并重新抛出。
  • 最外层的try...except语句最终捕获并处理CustomError,输出错误信息。
class CustomError(Exception):
    """自定义异常类"""
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return f"CustomError: {self.message}"

def read_file(file_path):
    try:
        with open(file_path, 'r') as file:
            return file.read()
    except FileNotFoundError as e:
        raise CustomError(f"File not found: {file_path}") from e

def process_file(file_path):
    try:
        content = read_file(file_path)
        # 假设这里有其他处理文件内容的代码
        return content
    except CustomError as ce:
        print(ce)
        raise

try:
    file_content = process_file("non_existent_file.txt")
except CustomError as ce:
    print(f"Handled at top level: {ce}")

结果如下:


网站公告

今日签到

点亮在社区的每一天
去签到