python 函数方法try 用法 案例

在Python中,try语句用于捕获和处理在代码块执行过程中可能发生的异常。try语句后面通常会跟着一个或多个except子句来指定不同类型的异常处理逻辑,以及一个可选的else子句来指定如果没有异常发生时要执行的代码,还有一个可选的finally子句来指定无论是否发生异常都要执行的清理代码。

下面是一些try语句在函数方法中的用法案例:

案例 1: 基本异常处理

def divide_numbers(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("Error: Cannot divide by zero.")
    else:
        print(f"Result: {result}")
    finally:
        print("Execution of try block is finished.")

# 使用示例
divide_numbers(10, 2)  # 输出: Result: 5.0 和 Execution of try block is finished.
divide_numbers(10, 0)  # 输出: Error: Cannot divide by zero. 和 Execution of try block is finished.

案例 2: 捕获多个异常类型

def read_file(filename):
    try:
        with open(filename, 'r') as file:
            data = file.read()
    except (FileNotFoundError, IOError) as e:
        print(f"Error reading file: {e}")
    else:
        print(f"File content: {data[:10]}...")  # 仅打印文件的前10个字符作为示例

# 使用示例
read_file('existent_file.txt')  # 假设这个文件存在
read_file('non_existent_file.txt')  # 假设这个文件不存在

案例 3: 获取异常信息

def risky_operation():
    try:
        # 这里可以是一些可能会引发异常的代码
        return 1 / 0
    except ZeroDivisionError as e:
        # 捕获异常并打印异常信息
        print(f"Caught an exception: {e}")

# 使用示例
risky_operation()  # 输出: Caught an exception: division by zero

案例 4: 重新引发异常

def safe_divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("Division by zero detected.")
        # 可以选择重新引发异常,让调用者知道发生了错误
        # raise  # 这将重新引发原始的ZeroDivisionError
        # 或者,可以引发一个新的异常类型,但最好提供足够的上下文信息
        raise ValueError("Cannot divide by zero in safe_divide function.") from None  # Python 3.3+

# 使用示例(注意:由于重新引发了异常,下面的代码将不会打印else块的内容)
try:
    result = safe_divide(10, 0)
except Exception as e:
    print(f"An error occurred: {e}")
else:
    print(f"Result: {result}")
# 输出: Division by zero detected.
#       An error occurred: Cannot divide by zero in safe_divide function.

注意:在案例4中,虽然raise语句被用来重新引发异常,但使用from None会丢失原始异常的堆栈跟踪。通常,如果你想要保留原始异常的堆栈跟踪,你应该在raise语句中指定原始异常,如raise ValueError(...) from e,其中e是捕获到的原始异常对象。然而,在这个特定的例子中,由于我们想要完全改变异常的类型和消息,并且不想保留原始的ZeroDivisionError堆栈跟踪作为新ValueError的一部分,所以我们使用了from None(尽管这不是最佳实践,因为它丢失了有关异常起源的有用信息)。在实际应用中,你应该仔细考虑是否确实需要改变异常类型,并确保提供足够的上下文信息来帮助调试和错误处理。

posted @ 2024-12-20 16:00  公子Learningcarer  阅读(8)  评论(0编辑  收藏  举报