随笔录--抛异常处理+案例

如何在Python程序中抛出异常,又不影响正常程序运行


在Python中,可以使用`try...except...`语句捕获异常。如果我们在程序中遇到了异常情况,可以使用`raise`语句主动抛出异常,从而触发`try...except...`块中的异常处理逻辑。如果我们希望抛出异常时不影响程序的正常运行,可以在异常处理块中添加一些代码来处理或忽略异常。

下面是一个简单的示例,演示了如何在Python中抛出异常并不影响程序的正常运行:

def divide(a, b):
    try:
        # 尝试计算 a/b 的值
        result = a / b
    except ZeroDivisionError:
        # 如果 b 为 0,抛出异常
        raise ValueError("Cannot divide by zero.")
    else:
        # 如果计算成功,返回计算结果
        return result

if __name__ == '__main__':
    nums = [(10, 2), (5, 0), (8, 4)]
    for a, b in nums:
        try:
            result = divide(a, b)
        except ValueError as e:
            # 捕获异常并打印错误信息,但不会影响程序的正常运行
            print(f"Error: {e}")
        else:
            print(f"{a}/{b} = {result}")

在上面的示例中,我们定义了一个名为`divide`的函数,它接受两个参数 a 和 b,并尝试计算 a/b 的值。如果 b 为 0,程序会抛出`ValueError`异常。

在程序的主逻辑中,我们使用一个循环遍历一个包含多个数字对的列表,并依次调用`divide`函数计算它们的商。如果在计算过程中出现异常,程序会捕获并打印错误信息,但不会影响后续的计算和程序的正常运行。

需要注意的是,在实际开发中,我们应该根据具体的业务需求和异常类型,合理地处理或忽略异常,避免对程序的稳定性和安全性造成影响。

自定义异常类型在实际应用中的用法和好处

假设我们正在编写一个学生信息管理系统,其中需要处理各种类型的异常,例如输入无效、文件读写错误、数据库连接失败等。我们可以定义多个自定义异常类型来表示不同类型的异常,并在程序中使用 `try-except` 块捕获并处理异常。以下是一个示例代码:


import csv
import sqlite3
from datetime import datetime

# 自定义异常类型:无效输入异常
class InvalidInputException(Exception):
    def __init__(self, message):
        self.message = message

# 自定义异常类型:文件读写异常
class FileIOException(Exception):
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

# 自定义异常类型:数据库连接异常
class DBConnectionException(Exception):
    def __init__(self, message):
        self.message = message

# 从 CSV 文件中读取学生信息
def read_student_info_from_csv(filename):
    try:
        with open(filename, "r") as f:
            reader = csv.reader(f)
            student_info_list = []
            for row in reader:
                if len(row) != 3:
                    raise InvalidInputException("无效输入:行格式不正确")
                student_info_list.append(row)
            return student_info_list
    except FileNotFoundError:
        raise FileIOException(filename, "r")

# 将学生信息保存到 SQLite 数据库中
def save_student_info_to_db(dbname, student_info):
    try:
        conn = sqlite3.connect(dbname)
        c = conn.cursor()
        c.execute("CREATE TABLE IF NOT EXISTS students (id INTEGER PRIMARY KEY, name TEXT, gender TEXT, birthday TEXT)")
        c.executemany("INSERT INTO students(name, gender, birthday) values (?, ?, ?)", student_info)
        conn.commit()
        conn.close()
    except sqlite3.Error as e:
        raise DBConnectionException("数据库连接异常:{}".format(str(e)))

# 主函数
def main():
    try:
        student_info_list = read_student_info_from_csv("student_info.csv")
        save_student_info_to_db("student_info.db", student_info_list)
        print("学生信息保存成功!")
    except InvalidInputException as e:
        print("无效输入异常:{}".format(e.message))
    except FileIOException as e:
        print("文件读写异常:无法打开文件 {},模式为 {}".format(e.filename, e.mode))
    except DBConnectionException as e:
        print(e.message)

if __name__ == "__main__":
    main()

解析

在上述代码中,我们定义了三个自定义异常类型
 `InvalidInputException`、`FileIOException` 和 `DBConnectionException`,
用于表示不同类型的异常。
在函数 `read_student_info_from_csv` 中,
我们尝试从 CSV 文件中读取学生信息。如果读取过程中发现行格式不正确,
则抛出 `InvalidInputException` 异常;
如果文件不存在,则抛出 `FileIOException` 异常。
在函数 `save_student_info_to_db` 中,我们将读取到的学生信息保存到 SQLite 数据库中。
如果连接数据库时出现异常,则抛出 `DBConnectionException` 异常。
在主函数中,我们使用 `try-except` 块捕获并处理不同类型的异常,
以便更好地处理错误情况并提供有用的信息。


这个示例代码演示了自定义异常类型在实际应用中的用法和好处。通过使用自定义异常类型,我们可以更好地组织异常处理逻辑、提高代码的可读性,并对不同类型的异常进行分类和处理。这有助于更好地理解程序中出现的问题,从而提高代码质量和可维护性。


Python的异常处理案例——网购平台交易案例

需求

假设有多条交易信息,写个raise抛出异常,try..except 负责梳理出正常数据有哪些和非正常数据有哪些?

class InvalidTransactionException(Exception):
    def __init__(self, message):
        self.message = message

def process_transactions(transactions):
    normal_transactions = []
    abnormal_transactions = []

    for transaction in transactions:
        try:
            if transaction["amount"] < 0 or transaction["amount"] > 100000:
                raise InvalidTransactionException("交易金额不合法")
            elif len(transaction["description"]) > 100:
                raise InvalidTransactionException("交易描述过长")
            else:
                normal_transactions.append(transaction)
        except InvalidTransactionException as e:
            transaction["error_message"] = e.message
            abnormal_transactions.append(transaction)

    return normal_transactions, abnormal_transactions

transactions = [
    {"id": 1, "amount": 100, "description": "购物"},
    {"id": 2, "amount": 200000, "description": "买车"},
    {"id": 3, "amount": -50, "description": "退款"},
    {"id": 4, "amount": 500, "description": "购物"*100},
    {"id": 5, "amount": 1000, "description": "旅游"},
]

normal_transactions, abnormal_transactions = process_transactions(transactions)

print("正常交易信息:")
for transaction in normal_transactions:
    print(transaction)

print("非正常交易信息:")
for transaction in abnormal_transactions:
    print(transaction)

在上述代码中,我们定义了一个自定义异常类型 `InvalidTransactionException`,用于表示交易信息不合法的异常。

在函数 `process_transactions` 中,我们遍历交易信息列表,并使用 `if` 语句检查每个交易信息。如果发现交易金额不合法或交易描述过长,则使用 `raise` 抛出 `InvalidTransactionException` 异常;否则,将其视为正常交易信息。

在 `except` 块中,我们捕获到 `InvalidTransactionException` 异常,并将错误信息添加到交易信息字典中的 `error_message` 键中。同时,将非正常交易信息添加到列表 `abnormal_transactions` 中。

最后,函数返回正常交易信息列表 `normal_transactions` 和非正常交易信息列表 `abnormal_transactions`。

在主程序中,我们定义了一个交易信息列表 `transactions`,然后调用 `process_transactions` 函数处理信息。最后,打印出正常交易信息和非正常交易信息。

更简单、更清晰的例子

使用 `raise` 抛出异常并使用 `try-except` 梳理出正常数据和非正常数据:

class InvalidDataException(Exception):
    pass

def process_data(data):
    normal_data = []
    abnormal_data = []

    for item in data:
        try:
            if item < 0:
                raise InvalidDataException("数据小于零")
            else:
                normal_data.append(item)
        except InvalidDataException:
            abnormal_data.append(item)

    return normal_data, abnormal_data

data = [1, 2, -3, 4, 5, -6, 7, 8, 9, -10]
normal_data, abnormal_data = process_data(data)

print("正常数据:", normal_data)
print("非正常数据:", abnormal_data)

在上述代码中,我们定义了一个自定义异常类型 `InvalidDataException`,用于表示数据不合法的异常。

在函数 `process_data` 中,我们遍历数据列表,并使用 `if` 语句检查每个数据项。如果发现数据小于零,则使用 `raise` 抛出 `InvalidDataException` 异常;否则,将其视为正常数据。

在 `except` 块中,我们捕获到 `InvalidDataException` 异常,并将非正常数据添加到列表 `abnormal_data` 中。

最后,函数返回正常数据列表 `normal_data` 和非正常数据列表 `abnormal_data`。

在主程序中,我们定义了一个数据列表 `data`,然后调用 `process_data` 函数处理数据。最后,打印出正常数据和非正常数据。

  • 42
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值