python的错误处理机制

在python中,一个错误可以分为两种:语法错误和异常。语法错误是指你的代码写得不符合python的规则,比如少了一个冒号或者括号不匹配。这种错误通常会在你运行程序之前就被发现,并且会提示你在哪一行出错了。

一,语法错误:

比如,如果你写了这样的代码:

# 定义一个函数
def print_hello()
    print("Hello, world!")

你会看到这样的错误信息:

  File "<stdin>", line 1
    def print_hello()
                    ^
SyntaxError: invalid syntax

这个错误信息告诉你,在第一行的最后,你少了一个冒号(:),这是一个语法错误。要修复这个错误,你只需要在函数名后面加上一个冒号就可以了。

二,异常:try…except…finally

异常是指你的代码写得符合python的规则,但是在执行时遇到了一些问题,比如除以零或者访问不存在的变量。这种错误通常会在你运行程序时才被发现,并且会提示你发生了什么异常以及在哪里发生了异常。比如,如果你写了这样的代码:

# 定义一个变量
x = 10

# 尝试用x除以0
y = x / 0

你会看到这样的错误信息:

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ZeroDivisionError: division by zero

这个错误信息告诉你,在第三行,你尝试用x除以0,这是一个除零错误(ZeroDivisionError),也就是一个异常。要修复这个错误,你需要避免用任何数除以0,或者用其他方式处理这个异常。

要处理异常,你可以使用try…except…finally语句。这个语句可以让你测试一段代码是否会发生异常,并且根据不同的异常类型来执行不同的操作(用try expect,处理多种错误的方法是在try语句后面跟上多个except语句,每个except语句指定一个或多个异常类型,并且可以执行相应的操作)。最后,如果没有发生任何异常,就会跳过所有的except语句。最后finally语句会被执行。你可以这样写代码:

# 尝试执行一段代码
try:
    # 定义两个变量
    x = 10
    y = "a"

    # 尝试用x除以y
    z = x / y

# 如果发生除零错误,执行以下操作
except ZeroDivisionError:
    # 打印一条提示信息
    print("You can't divide by zero!")

# 如果发生类型错误,执行以下操作
except TypeError:
    # 打印一条提示信息
    print("You can't divide by different types!")

# 如果发生值错误,执行以下操作
except ValueError:
    # 打印一条提示信息
    print("You can't divide by an invalid value!")

# 如果发生其他类型的错误,执行以下操作
except Exception as e:
    # 打印出错的类型和信息
    print(f"An error occurred: {type(e)}: {e}")

# 无论是否发生错误,都执行以下操作
finally:
    # 打印一条结束信息
    print("The program is finished.")

你会看到这样的输出:

You can't divide by zero!
The program is finished.

这个输出告诉你,在try语句中,发生了一个除零错误(ZeroDivisionError),所以except ZeroDivisionError语句被执行,并打印出了一条提示信息。然后finally语句被执行,并打印出了一条结束信息。

如果你把代码中的y = x / 0改成y = x / z,你会看到这样的输出:

An error occurred: <class 'NameError'>: name 'z' is not defined
The program is finished.

这个输出告诉你,在try语句中,发生了一个名字错误(NameError),因为变量z没有被定义。所以except Exception as e语句被执行,并打印出了出错的类型和信息。然后finally语句被执行,并打印出了一条结束信息。

如果你把代码中的y = x / 0改成y = x / 2,你会看到这样的输出:

The program is finished.

这个输出告诉你,在try语句中,没有发生任何错误,所以except语句都没有被执行。只有finally语句被执行,并打印出了一条结束信息。

三,自定义异常类型

python中有很多种不同类型的异常,它们都有自己的名字和含义。比如,ZeroDivisionError表示除零错误,NameError表示名字错误,TypeError表示类型错误,ValueError表示值错误等等。如果你想了解更多关于python中异常的类型和含义,请参考以下网页

要定义自己的异常类型,你可以创建一个新的类,这个类继承自内置的Exception类或者它的子类之一。比如,如果你想定义一个表示温度范围错误的异常类型,你可以这样写:

# 定义一个温度范围错误类,它继承自ValueError类
class TemperatureRangeError(ValueError):
    # 定义一个初始化方法,接受温度值和信息作为参数
    def __init__(self, temperature, message):
        # 调用父类的初始化方法
        super().__init__(message)
        # 保存温度值作为属性
        self.temperature = temperature

这样,你就定义了一个自己的异常类型TemperatureRangeError,它继承自ValueError类,并且接受温度值和信息作为参数。要抛出这个异常,你可以使用raise语句:

# 定义一个函数,用来检查温度是否在合理范围内
def check_temperature(temperature):
    # 如果温度小于-273.15摄氏度或者大于100摄氏度
    if temperature < -273.15 or temperature > 100:
        # 抛出温度范围错误异常,并传入温度值和信息
        raise TemperatureRangeError(temperature, "Temperature is out of range")

# 调用函数,并传入一个不合理的温度值
check_temperature(-300)

这样,当你调用函数时,就会抛出温度范围错误异常,并显示以下信息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in check_temperature
__main__.TemperatureRangeError: Temperature is out of range

要捕获这个异常,你可以使用try…except语句:

# 尝试执行一段代码
try:
    # 调用函数,并传入一个不合理的温度值
    check_temperature(-300)
# 如果捕获到温度范围错误异常,并把异常对象存储到变量e中
except TemperatureRangeError as e:
    # 打印出错的温度值和信息(通过e.temperature来访问异常对象的温度属性,或者通过str(e)来获取异常对象的信息字符串,并打印出来。)
    print(f"The temperature {e.temperature} is out of range: {e}")

这样,当你执行try语句时,就会捕获到温度范围错误异常,并打印以下信息:

The temperature -300 is out of range: Temperature is out of range

四,Raise语句的用法

raise语句是一种用来抛出异常的语法,它可以让你在程序中主动触发一个错误或者提示一个问题。raise语句有以下几种用法:

  • raise <异常类型>:这种用法可以抛出一个指定类型的异常,比如raise ZeroDivisionError或者raise ValueError。你可以选择使用python内置的异常类型,或者自定义的异常类型。
# 定义一个函数,用来计算两个数的商
def divide(a, b):
    # 如果除数是0
    if b == 0:
        # 抛出一个除零错误异常
        raise ZeroDivisionError("You can't divide by zero!")
    # 否则,返回两个数的商
    return a / b

# 调用函数,并传入两个数
print(divide(10, 2)) # 输出 5.0
print(divide(10, 0)) # 抛出 ZeroDivisionError: You can't divide by zero!
  • raise <异常类型>(<信息>):这种用法可以抛出一个指定类型的异常,并且附加一些信息,比如raise ZeroDivisionError(“You can’t divide by zero!”)或者raise ValueError(“Invalid input”).这些信息可以帮助你或者用户更好地理解发生了什么问题。
# 定义一个函数,用来检查输入是否是整数
def check_input(input):
    # 尝试把输入转换成整数
    try:
        x = int(input)
    # 如果发生类型错误异常
    except TypeError:
        # 抛出一个值错误异常,并附加信息
        raise ValueError("Invalid input: expected an integer") from TypeError("Expected an integer")

# 调用函数,并传入一个输入
check_input("abc") # 抛出 ValueError: Invalid input: expected an integer
  • raise <异常对象>:这种用法可以抛出一个已经创建好的异常对象,比如ex = ZeroDivisionError(“You can’t divide by zero!”),然后raise ex。这样可以让你在抛出异常之前对异常对象进行一些操作或修改。
# 定义一个函数,用来计算两个数的商
def divide(a, b):
    # 如果除数是0
    if b == 0:
        # 创建一个除零错误异常对象,并保存到变量ex中
        ex = ZeroDivisionError("You can't divide by zero!")
        # 给异常对象添加一个属性,表示被除数的值
        ex.dividend = a
        # 抛出异常对象
        raise ex
    # 否则,返回两个数的商
    return a / b

# 尝试执行一段代码
try:
    # 调用函数,并传入两个数
    print(divide(10, 0))
# 如果捕获到除零错误异常,并把异常对象存储到变量e中
except ZeroDivisionError as e:
    # 打印出错的信息和被除数的值
    print(f"{e}: the dividend is {e.dividend}") # 输出 You can't divide by zero!: the dividend is 10
  • raise:这种用法可以重新抛出之前捕获到的异常,比如在try…except语句中,如果你想在处理完异常后再次抛出它,你可以在except语句中使用raise。
# 定义一个函数,用来计算两个数的商
def divide(a, b):
    # 如果除数是0
    if b == 0:
        # 抛出一个除零错误异常
        raise ZeroDivisionError("You can't divide by zero!")
    # 否则,返回两个数的商
    return a / b

# 尝试执行一段代码
try:
    # 调用函数,并传入两个数
    print(divide(10, 0))
# 如果捕获到除零错误异常,并把异常对象存储到变量e中
except ZeroDivisionError as e:
    # 打印出错的信息
    print(f"An error occurred: {e}")
    # 重新抛出捕获到的异常
    raise
  • raise <异常类型> from <原因>:这种用法可以抛出一个指定类型的异常,并且指明导致这个异常的原因,比如raise ValueError(“Invalid input”) from TypeError(“Expected an integer”).这样可以让你创建一个异常链,显示出错误的来源和传播。
# 定义一个函数,用来检查输入是否是整数
def check_input(input):
    # 尝试把输入转换成整数
    try:
        x = int(input)
    # 如果发生类型错误异常
    except TypeError:
        # 抛出一个值错误异常,并指明原因
        raise ValueError("Invalid input: expected an integer") from TypeError("Expected an integer")

# 调用函数,并传入一个输入
check_input("abc") # 抛出 ValueError: Invalid input: expected an integer

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in check_input
TypeError: Expected an integer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值