展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > 5 个实用的Python错误处理函数详解

5 个实用的Python错误处理函数详解

错误处理往往是优秀代码中最薄弱的环节。 像缺失主键、请求失败、函数运行时间过长这些问题,在实际项目中几乎天天都能碰到。 Python 自带的 try-except 块确实有用,但光靠它还真不够——很多真实场景根本覆盖不到。 更好的思路是:把常见的失败情形封装成小巧、可复用的函数,比如带限制的重试、输

错误处理往往是优秀代码中最薄弱的环节。

5 个实用的Python错误处理函数详解

像缺失主键、请求失败、函数运行时间过长这些问题,在实际项目中几乎天天都能碰到。

Python 自带的 try-except 块确实有用,但光靠它还真不够——很多真实场景根本覆盖不到。

更好的思路是:把常见的失败情形封装成小巧、可复用的函数,比如带限制的重试、输入验证,还有防止代码跑太久超时的保护机制。

下面这五个错误处理函数,在网页抓取、API 构建、用户数据处理这些任务里都很实用,可以直接拿来用。

使用指数退避重试失败操作

很多项目里,API 调用和网络请求失败是家常便饭。新手往往只试一次,捕获异常记录一下就停了。其实更好的做法是重试——但怎么重试很关键。指数退避就是这把钥匙:与其在失败服务上拼命连发请求(只会让情况更糟),不如每次尝试之间等一会儿,1秒、2秒、4秒,逐渐拉长。

我们来写一个实现这个功能的装饰器:

import time
import functools
from typing import Callable, Type, Tuple
def retry_with_backoff(
    max_attempts: int = 3,
    base_delay: float = 1.0,
    exponential_base: float = 2.0,
    exceptions: Tuple[Type[Exception], ...] = (Exception,),
):
    """
    使用指数退避算法重试函数的装饰器。
    参数:
        max_attempts: 最大重试次数
        base_delay: 初始等待时间(秒)
        exponential_base: 指数基数(2.0 表示每次等待时间翻倍)
        exceptions: 需要捕获并重试的异常类型元组
    """
    def decorator(func: Callable):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            # 尝试执行函数,最多执行 max_attempts 次
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_exception = e
                    # 如果还有剩余重试次数,则计算等待时间并休眠
                    if attempt < max_attempts - 1:
                        delay = base_delay * (exponential_base ** attempt)
                        print(f"第 {attempt + 1} 次尝试失败: {e}")
                        print(f"将在 {delay:.1f} 秒后重试...")
                        time.sleep(delay)
                    else:
                        # 所有尝试均失败,抛出最后一次异常
                        print(f"所有 {max_attempts} 次尝试均失败")
                        raise last_exception
            # 理论上不会执行到这里,因为要么返回结果,要么抛出异常
            # 但为了类型检查器的完整性,保留此结构
        return wrapper
    return decorator

这个装饰器会把你的函数包起来,并捕获指定的异常。核心计算是 delay = base_delay * (exponential_base ** attempt)。当 base_delay=1、exponential_base=2 时,延迟时间依次为1秒、2秒、4秒、8秒——给压力下的系统留出恢复时间。

exceptions 参数让你可以指定哪些错误需要重试。比如,你可以重试 ConnectionError 但不重试 ValueError,因为连接问题是暂时的,而验证错误不是。

看看实际效果:

if __name__ == "__main__":
    counter = 0
    @retry_with_backoff(max_attempts=3, base_delay=0.5, exceptions=(ValueError,))
    def unstable_function():
        global counter
        counter += 1
        print(f"正在执行函数,当前调用次数: {counter}")
        if counter < 3:
            raise ValueError("模拟临时性错误")
        return "成功!"
    try:
        result = unstable_function()
        print(f"最终结果: {result}")
    except Exception as e:
        print(f"未处理的异常: {e}")

使用可组合规则验证输入

用户输入验证这件事,既繁琐又重复。要检查字符串是否为空、数字是否在范围内、邮箱格式是否正确……不知不觉,代码里就塞满了嵌套的 if 语句,乱成一团。

我们来搞一个简单易用的验证系统。先定义一个自定义异常:

from typing import Any, Callable, Dict, List, Optional
class ValidationError(Exception):
    """当验证失败时抛出的异常。"""
    def __init__(self, field: str, errors: List[str]):
        self.field = field
        self.errors = errors
        # 调用父类构造函数,设置异常消息为字段名和错误列表的组合
        super().__init__(f"{field}: {', '.join(errors)}")

这个异常可以包含多条错误信息。验证失败时,我们希望把问题一次性全告诉用户,而不是只报第一个。

然后是验证器本身:

def validate_input(
    value: Any,
    field_name: str,
    rules: Dict[str, Callable[[Any], bool]],
    messages: Optional[Dict[str, str]] = None
) -> Any:
    """
    根据多条规则验证输入。
    参数:
        value: 待验证的值
        field_name: 字段名称,用于错误提示
        rules: 字典,键为规则名称,值为验证函数 (接受值,返回布尔值)
        messages: 可选字典,键为规则名称,值为自定义错误消息
    返回:
        如果验证通过,返回原始值
    异常:
        ValidationError: 如果任何规则验证失败
    """
    if messages is None:
        messages = {}
    errors = []
    # 遍历所有验证规则
    for rule_name, rule_func in rules.items():
        try:
            # 执行验证函数
            if not rule_func(value):
                # 如果验证失败,获取自定义错误消息或默认消息
                error_msg = messages.get(
                    rule_name, f"未通过验证规则: {rule_name}"
                )
                errors.append(error_msg)
        except Exception as e:
            # 如果在执行验证规则过程中发生异常(例如类型转换错误),也视为验证失败
            errors.append(f"规则 '{rule_name}' 执行出错: {str(e)}")
    # 如果存在错误,抛出验证异常
    if errors:
        raise ValidationError(field_name, errors)
    return value

在 rules 字典里,每个规则都是一个返回 True 或 False 的函数。这样规则就可以组合、复用。

来创建一些常用的验证规则:

# --- 可复用的验证规则工厂函数 ---
def not_empty(value: Any) -> bool:
    """检查值是否非空(针对字符串去除空白后)"""
    if isinstance(value, str):
        return bool(value.strip())
    return bool(value)
def min_length(min_len: int) -> Callable[[Any], bool]:
    """生成一个检查最小长度的验证函数"""
    def _validator(value: Any) -> bool:
        try:
            return len(str(value)) >= min_len
        except Exception:
            return False
    return _validator
def max_length(max_len: int) -> Callable[[Any], bool]:
    """生成一个检查最大长度的验证函数"""
    def _validator(value: Any) -> bool:
        try:
            return len(str(value)) <= max_len
        except Exception:
            return False
    return _validator
def in_range(min_val: float, max_val: float) -> Callable[[Any], bool]:
    """生成一个检查数值范围的验证函数"""
    def _validator(value: Any) -> bool:
        try:
            num_value = float(value)
            return min_val <= num_value <= max_val
        except (ValueError, TypeError):
            # 如果无法转换为浮点数,则验证失败
            return False
    return _validator

注意,min_length、max_length 和 in_range 都是工厂函数。它们返回配置了特定参数的验证函数。这样你就可以写 min_length(3),而不必为每个长度要求都新建一个函数。

测试一下验证用户名:

try:
    username = validate_input(
        "ab",  # 输入值
        "username",  # 字段名
        {
            "not_empty": not_empty,
            "min_length": min_length(3),
            "max_length": max_length(20),
        },
        messages={
            "not_empty": "用户名不能为空",
            "min_length": "用户名长度至少为 3 个字符",
            "max_length": "用户名长度不能超过 20 个字符",
        }
    )
    print(f"验证通过的用户名: {username}")
except ValidationError as e:
    print(f"验证失败: {e}")

输出:

验证失败: username: 用户名长度至少为 3 个字符

这种方法扩展性很好。规则定义一次,按需组合,就能得到清晰的错误信息。

安全地访问嵌套字典

访问嵌套字典常常让人头疼。键不存在会抛出 KeyError,对字符串做下标操作会抛出 TypeError,代码里塞满了一连串的 .get() 调用或防御性的 try-except 块。处理来自 API 的 JSON 数据时,这个问题尤其突出。

来写一个能安全访问嵌套结构的函数:

from typing import Any, Optional, List, Union
def safe_get(
    data: dict,
    path: Union[str, List[str]],
    default: Any = None,
    separator: str = "."
) -> Any:
    """
    从嵌套字典中安全地获取值。
    参数:
        data: 要访问的字典
        path: 点分路径 (例如 "user.address.city") 或键名列表
        default: 如果路径不存在时返回的默认值
        separator: 用于分割路径字符串的分隔符 (默认: ".")
    返回:
        路径对应的值,如果未找到则返回 default
    """
    # 如果路径是字符串,将其分割为键名列表
    if isinstance(path, str):
        keys = path.split(separator)
    else:
        keys = path
    current = data
    for key in keys:
        try:
            # 处理列表索引:如果当前层级是列表,尝试将键转换为整数索引
            if isinstance(current, list):
                try:
                    index = int(key)
                    current = current[index]
                except (ValueError, TypeError, IndexError):
                    # 如果转换失败或索引越界,返回默认值
                    return default
            elif isinstance(current, dict):
                # 如果当前层级是字典,正常按键获取
                current = current[key]
            else:
                # 如果当前层级既不是字典也不是列表(例如是字符串或数字),无法继续深入
                return default
        except (KeyError, IndexError, TypeError):
            # 捕获键错误、索引错误或类型错误,返回默认值
            return default
    return current

这个函数把路径拆成一个个键,然后逐步往下走。如果某个键不存在,或者试图对不可下标对象操作,它会返回默认值而不是崩溃。还能自动处理列表索引——如果当前值是列表且键是数字,则会将键转换为整数。

配套的设置函数如下:

def safe_set(
    data: dict,
    path: Union[str, List[str]],
    value: Any,
    separator: str = ".",
    create_missing: bool = True
) -> bool:
    """
    安全地在嵌套字典中设置值。
    参数:
        data: 要修改的字典
        path: 点分路径或键名列表
        value: 要设置的值
        separator: 用于分割路径字符串的分隔符
        create_missing: 是否创建缺失的中间字典节点
    返回:
        如果设置成功返回 True,否则返回 False
    """
    # 将路径字符串分割为键名列表
    if isinstance(path, str):
        keys = path.split(separator)
    else:
        keys = path
    # 如果路径为空,无法设置
    if not keys:
        return False
    current = data
    # 遍历到最后一个键的父节点
    for key in keys[:-1]:
        # 如果当前节点不存在
        if key not in current:
            if create_missing:
                # 如果允许创建缺失节点,则创建一个新的空字典
                current[key] = {}
            else:
                # 如果不允许创建,则设置失败
                return False
        # 移动到下一层
        next_node = current[key]
        # 检查下一层是否是字典,因为只有字典才能包含子键
        # 注意:这里不支持在列表中自动插入元素,只支持字典嵌套
        if not isinstance(next_node, dict):
            # 如果中间节点存在但不是字典(例如是列表或基本类型),无法继续深入设置
            return False
        current = next_node
    # 设置最终的值
    try:
        final_key = keys[-1]
        # 如果最后一层是列表,尝试作为索引设置(可选功能,这里简化为仅支持字典键)
        # 为了保持简单和一致性,safe_set 主要针对字典结构。
        # 如果用户希望设置列表元素,通常需要先确保列表存在且长度足够,这比较复杂。
        # 此处我们假设最终目标是一个字典的键。
        current[final_key] = value
        return True
    except Exception:
        return False

safe_set 会在需要时创建嵌套结构并设置值。动态构建字典时特别有用。

测试一下这两个函数:

if __name__ == "__main__":
    # 示例嵌套数据
    user_data = {
        "user": {
            "name": "Anna",
            "address": {
                "city": "San Francisco",
                "zip": "94105"
            },
            "orders": [
                {"id": 1, "total": 99.99},
                {"id": 2, "total": 149.50}
            ]
        }
    }
    print("--- Safe Get 测试 ---")
    # 1. 获取存在的城市
    city = safe_get(user_data, "user.address.city")
    print(f"城市: {city}")
    # 2. 获取不存在的国家,使用默认值
    country = safe_get(user_data, "user.address.country", default="Unknown")
    print(f"国家: {country}")
    # 3. 获取列表中的第一个订单总额
    # 注意:路径中的 "0" 会被识别为列表索引
    first_order_total = safe_get(user_data, "user.orders.0.total")
    print(f"第一笔订单总额: ${first_order_total}")
    # 4. 获取深层不存在的路径
    missing = safe_get(user_data, "user.profile.bio", default="No bio")
    print(f"个人简介: {missing}")
    # 5. 尝试在非字典节点上继续获取 (orders 是列表,不能直接用 .id 获取所有 ID,只能索引)
    invalid_path = safe_get(user_data, "user.orders.id", default="Invalid Path")
    print(f"无效路径结果: {invalid_path}")
    print("n--- Safe Set 测试 ---")
    # 1. 在空字典中创建深层结构
    new_data = {}
    success = safe_set(new_data, "user.settings.theme", "dark")
    print(f"设置主题成功: {success}")
    print(f"新数据结构: {new_data}")
    # 2. 修改已存在的值
    success = safe_set(user_data, "user.address.city", "New York")
    print(f"修改城市成功: {success}")
    print(f"新城市: {safe_get(user_data, 'user.address.city')}")
    # 3. 尝试在不允许创建缺失节点的情况下设置
    temp_data = {"a": 1}
    success = safe_set(temp_data, "a.b.c", "value", create_missing=False)
    print(f"在不允许创建缺失节点时设置深层路径成功: {success}") # 应为 False,因为 a 是整数不是字典
    # 4. 覆盖非字典节点
    overwrite_data = {"x": {"y": "old"}}
    # 先将 y 设置为一个字典,以便后续可以在其下设置 z
    safe_set(overwrite_data, "x.y", {"z": "new"})
    success = safe_set(overwrite_data, "x.y.z", "final_value")
    print(f"覆盖后设置深层值成功: {success}")
    print(f"最终值: {safe_get(overwrite_data, 'x.y.z')}")

输出:

--- Safe Get 测试 ---
城市: San Francisco
国家: Unknown
第一笔订单总额: $99.99
个人简介: No bio
无效路径结果: Invalid Path
--- Safe Set 测试 ---
设置主题成功: True
新数据结构: {'user': {'settings': {'theme': 'dark'}}}
修改城市成功: True
新城市: New York
在不允许创建缺失节点时设置深层路径成功: False
覆盖后设置深层值成功: True
最终值: final_value

这种模式能消除防御性编程的杂乱代码,在处理 JSON、配置文件或任何深层嵌套数据时,代码会干净很多。

为长时间运行的操作强制设置超时

有些操作就是会耗太长时间。数据库查询可能挂起,网页抓取可能卡在慢速服务器上,计算也可能永远跑下去。你需要一种方法来设定时间限制并及时退出。

下面是一个使用线程的超时装饰器:

import threading
import functools
import time
from typing import Callable, Optional, Any
class TimeoutError(Exception):
    """当操作超过指定超时时限后抛出的异常。"""
    pass
def timeout(seconds: float, error_message: Optional[str] = None):
    """
    一个用于强制函数执行超时的装饰器。
    注意:此实现使用线程。由于 Python 的 GIL 和线程机制,
    它无法真正“杀死”正在运行的线程,只能停止等待并抛出异常。
    后台线程可能会继续运行直到完成,但其结果将被忽略。
    参数:
        seconds: 最大执行时间(秒)
        error_message: 超时时的自定义错误消息
    返回:
        装饰器函数
    """
    if seconds < 0:
        raise ValueError("超时时间不能为负数")
    def decorator(func: Callable) -> Callable:
        @functools.wraps(func)
        def wrapper(*args, **kwargs) -> Any:
            # 使用列表来存储结果或异常,因为列表是可变对象,可以在闭包中修改
            # 初始化为 None,表示尚未完成
            result_container = [None]
            exception_container = [None]
            def target():
                try:
                    # 执行目标函数
                    result_container[0] = func(*args, **kwargs)
                except Exception as e:
                    # 捕获函数内部抛出的任何异常
                    exception_container[0] = e
            # 创建并启动线程
            thread = threading.Thread(target=target)
            thread.daemon = True  # 设置为守护线程,主程序退出时自动结束
            thread.start()
            # 等待线程完成,最多等待 seconds 秒
            thread.join(timeout=seconds)
            # 检查线程是否仍在运行(即是否超时)
            if thread.is_alive():
                # 如果超时,抛出 TimeoutError
                # 注意:线程实际上仍在后台运行,但我们不再关心其结果
                raise TimeoutError(
                    error_message or f"操作在 {seconds} 秒后超时"
                )
            # 如果线程已结束,检查是否有异常
            if exception_container[0] is not None:
                raise exception_container[0]
            # 返回正常结果
            return result_container[0]
        return wrapper
    return decorator

这个装饰器在单独的线程里运行你的函数,并用 thread.join(timeout=seconds) 来等待。如果超时后线程还在跑,我们就知道它超时了,于是抛出 TimeoutError。结果存在一个列表(可变容器)里,方便内部线程修改。如果线程里发生了异常,我们会在主线程中重新抛出。

⚠️ 一个限制:即使超时了,线程仍然会在后台继续运行。对大多数场景来说这没问题,但如果有副作用,就需要格外小心。

测试一下:

if __name__ == "__main__":
    print("--- 测试 1: 模拟慢速数据库查询 (应超时) ---")
    @timeout(2, error_message="查询耗时过长")
    def slow_database_query():
        """模拟一个慢速查询。"""
        time.sleep(5)
        return "查询结果"
    try:
        result = slow_database_query()
        print(f"结果: {result}")
    except TimeoutError as e:
        print(f"超时错误: {e}")
    print("n--- 测试 2: 模拟快速数据获取 (应成功) ---")
    @timeout(3)
    def fetch_data():
        """模拟一个快速操作。"""
        time.sleep(1)
        return {"data": "value"}
    try:
        data = fetch_data()
        print(f"成功: {data}")
    except TimeoutError as e:
        print(f"超时错误: {e}")
    print("n--- 测试 3: 函数内部抛出异常 ---")
    @timeout(5)
    def faulty_function():
        """模拟一个会抛出异常的函数。"""
        raise ValueError("内部错误")
    try:
        faulty_function()
    except ValueError as e:
        print(f"捕获到内部异常: {e}")
    except TimeoutError as e:
        print(f"超时错误: {e}")
    print("n--- 测试 4: 刚好在超时前完成 ---")
    @timeout(2)
    def just_in_time():
        """模拟一个刚好在超时前完成的操作。"""
        time.sleep(1.9)
        return "及时完成"
    try:
        result = just_in_time()
        print(f"结果: {result}")
    except TimeoutError as e:
        print(f"超时错误: {e}")

输出:

--- 测试 1: 模拟慢速数据库查询 (应超时) ---
超时错误: 查询耗时过长
--- 测试 2: 模拟快速数据获取 (应成功) ---
成功: {'data': 'value'}
--- 测试 3: 函数内部抛出异常 ---
捕获到内部异常: 内部错误
--- 测试 4: 刚好在超时前完成 ---
结果: 及时完成

这种模式对构建响应式应用至关重要。抓取网站、调用外部 API 或运行用户代码时,超时能防止程序无限挂起。

使用自动清理管理资源

打开文件、数据库连接、网络套接字,都需要仔细清理。如果发生异常,你得确保资源被释放。用 with 语句可以处理这种情况,但有时你需要更灵活的控制。

来构建一个灵活的上下文管理器,支持自动资源清理:

from contextlib import contextmanager
from typing import Callable, Any, Optional
import traceback
@contextmanager
def managed_resource(
    acquire: Callable[[], Any],
    release: Callable[[Any], None],
    on_error: Optional[Callable[[Exception, Any], None]] = None,
    suppress_errors: bool = False
):
    """
    用于自动获取和清理资源的上下文管理器。
    参数:
        acquire: 获取资源的函数
        release: 释放资源的函数
        on_error: 可选的错误处理函数,接收异常对象和资源对象
        suppress_errors: 是否在清理后抑制异常(即不重新抛出)
    注意:
        如果发生异常,执行顺序为:
. 调用 on_error (如果提供且资源已获取)
. 如果 suppress_errors 为 False,则重新抛出原始异常
. 始终执行 release (在 finally 块中)
    """
    resource = None
    try:
        # 获取资源
        resource = acquire()
        # 将资源 yield 给 with 块使用
        yield resource
    except Exception as e:
        # 如果在 with 块中发生异常
        if on_error and resource is not None:
            try:
                # 调用自定义错误处理器
                on_error(e, resource)
            except Exception as handler_error:
                # 如果错误处理器本身出错,打印警告,但不掩盖原始异常
                print(f"错误处理器执行出错: {handler_error}")
                traceback.print_exc()
        # 根据配置决定是否抑制异常
        if not suppress_errors:
            raise
    finally:
        # 无论是否发生异常,都尝试释放资源
        if resource is not None:
            try:
                release(resource)
            except Exception as cleanup_error:
                # 如果清理过程中间出错,打印错误信息
                print(f"资源清理过程中间出错: {cleanup_error}")
                traceback.print_exc()

managed_resource 是一个上下文管理器工厂。它接受两个必需函数:一个获取资源,一个释放资源。释放函数始终在 finally 块中运行,保证即使发生异常也会执行清理。

可选的 on_error 参数让你可以在异常传播之前处理它——日志记录、发送警报或尝试恢复都很方便。suppress_errors 标志决定异常是否被抛出还是被抑制。

下面是一个辅助类,用于演示资源操作:

# --- 辅助类:资源追踪器 ---
class ResourceTracker:
    """用于追踪资源操作的辅助类。"""
    def __init__(self, name: str, verbose: bool = True):
        self.name = name
        self.verbose = verbose
        self.operations = []
    def log(self, operation: str):
        """记录操作并可选地打印。"""
        self.operations.append(operation)
        if self.verbose:
            print(f"[{self.name}] {operation}")
    def acquire(self):
        """模拟获取资源。"""
        self.log("正在获取资源")
        return self
    def release(self):
        """模拟释放资源。"""
        self.log("正在释放资源")
    def use(self, action: str):
        """模拟使用资源执行操作。"""
        self.log(f"使用资源执行: {action}")

测试这个上下文管理器:

# --- 测试示例 ---
if __name__ == "__main__":
    print("--- 测试 1: 带错误处理的正常异常流程 ---")
    tracker1 = ResourceTracker("Database")
    def error_handler(exception, resource):
        resource.log(f"捕获到错误: {exception}")
        resource.log("尝试执行回滚操作")
    try:
        with managed_resource(
            acquire=lambda: tracker1.acquire(),
            release=lambda r: r.release(),
            on_error=error_handler
        ) as db:
            db.use("INSERT INTO users")
            raise ValueError("重复条目错误")
    except ValueError as e:
        print(f"主程序捕获到异常: {e}")
    print("n--- 测试 2: 成功执行无异常 ---")
    tracker2 = ResourceTracker("FileHandle")
    try:
        with managed_resource(
            acquire=lambda: tracker2.acquire(),
            release=lambda r: r.release()
        ) as file:
            file.use("Write data")
        print("操作成功完成")
    except Exception as e:
        print(f"意外异常: {e}")
    print("n--- 测试 3: 抑制异常 ---")
    tracker3 = ResourceTracker("NetworkSocket")
    try:
        with managed_resource(
            acquire=lambda: tracker3.acquire(),
            release=lambda r: r.release(),
            suppress_errors=True
        ) as sock:
            sock.use("Send packet")
            raise ConnectionError("连接丢失")
    except Exception as e:
        print(f"此异常应被抑制,不应打印: {e}")
    else:
        print("异常已被抑制,程序继续执行")
    print("n--- 测试 4: 清理过程中间出错 ---")
    tracker4 = ResourceTracker("BadResource")
    def bad_release(r):
        r.log("尝试释放... 失败!")
        raise RuntimeError("释放失败")
    try:
        with managed_resource(
            acquire=lambda: tracker4.acquire(),
            release=bad_release
        ) as res:
            res.use("Do something")
    except Exception as e:
        print(f"主程序未捕获到清理异常(因为它在 finally 中被捕获并打印): {type(e).__name__}")

输出:

--- 测试 1: 带错误处理的正常异常流程 ---
[Database] 正在获取资源
[Database] 使用资源执行: INSERT INTO users
[Database] 捕获到错误: 重复条目错误
[Database] 尝试执行回滚操作
[Database] 正在释放资源
主程序捕获到异常: 重复条目错误
--- 测试 2: 成功执行无异常 ---
[FileHandle] 正在获取资源
[FileHandle] 使用资源执行: Write data
[FileHandle] 正在释放资源
操作成功完成
--- 测试 3: 抑制异常 ---
[NetworkSocket] 正在获取资源
[NetworkSocket] 使用资源执行: Send packet
[NetworkSocket] 正在释放资源
异常已被抑制,程序继续执行
--- 测试 4: 清理过程中间出错 ---
[BadResource] 正在获取资源
[BadResource] 使用资源执行: Do something
[BadResource] 尝试释放... 失败!
资源清理过程中间出错: 释放失败
Traceback (most recent call last):
  File "...", line ..., in managed_resource
    release(resource)
  File "...", line ..., in bad_release
    raise RuntimeError("释放失败")
RuntimeError: 释放失败
主程序未捕获到清理异常(因为它在 finally 中被捕获并打印): Exception

这种模式对管理数据库连接、文件句柄、网络套接字、锁以及任何需要保证清理的资源都非常有用。它能防止资源泄漏,让代码更安全。

总结

文中每个函数都针对一个特定的错误处理挑战:

  • 重试临时性故障
  • 系统化验证输入
  • 安全访问嵌套数据
  • 防止操作挂起
  • 管理资源清理

这些模式在 API 集成、数据处理管道、网页抓取和面向用户的应用中反复出现。

文中使用的技术包括装饰器、上下文管理器和可组合函数,让错误处理不再重复繁琐,更加可靠。

你可以将这些函数直接放入项目中使用,也可以根据具体需求调整。

它们独立、易懂,能解决日常工作中切实遇到的麻烦。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发 Python
上一篇: 蓝云怎么使用
相关文章 更多
精品专题 更多
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

Mac软件 更多
WPS Office macOS版
WPS Office macOS版

WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,

Shapr3D macOS版
Shapr3D macOS版

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

Ableton Live macOS版
Ableton Live macOS版

Ableton Live 是面向音乐制作人与现场表演者的数字音频工作站,提供编曲视图、独具特色的现场视图、音频录制、MIDI创作、实时变速、乐器及效果器。Mac版原生支持Apple芯片,并可连接音频接口、MIDI控制器和第三方插件。

Adobe After Effects macOS版
Adobe After Effects macOS版

Adobe After Effects 是面向动态图形、影视特效与视频合成的专业创作软件。它提供关键帧动画、遮罩抠像、运动跟踪、三维空间、文字动画和表达式等工具,并可与 Premiere Pro、Photoshop、Illustrator

Adobe Audition macOS版
Adobe Audition macOS版

Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

Adobe Bridge macOS版
Adobe Bridge macOS版

Adobe Bridge 是面向摄影师、设计师及内容团队的免费数字资产管理工具,可集中预览照片、视频和 Adobe 项目文件,并利用评级、标签、关键词、元数据、筛选与收藏集完成分类检索。它还支持批量重命名、格式导出、相机导入及 Camera

Adobe Illustrator macOS版
Adobe Illustrator macOS版

Adobe Illustrator 是 Adobe 推出的专业矢量图形设计软件,适合在 Mac 上制作标志、图标、插画、包装、信息图及印刷版面。它以路径和锚点构建可无损缩放的图形,并提供钢笔、形状、文字、图像描摹、渐变、画板及生成式功能。

Adobe InDesign macOS版
Adobe InDesign macOS版

Adobe InDesign 是面向印刷品与数字出版物的专业版面设计软件,可在 Mac 上制作书籍、杂志、宣传册、海报、报告及交互式文档。它提供精细的文字样式、网格、母版、长文档管理和印前输出能力。

Adobe Lightroom Classic macOS版
Adobe Lightroom Classic macOS版

Adobe Lightroom Classic 是面向桌面摄影工作流的照片管理与后期处理软件,可将原始照片保存在本地硬盘,通过目录、关键词、评分和收藏夹高效整理图库,并提供 RAW 冲印、蒙版、镜头校正、批量同步及多格式导出等功能。

Adobe Media Encoder macOS版
Adobe Media Encoder macOS版

Adobe Media Encoder 是 Adobe 推出的专业音视频编码与转码工具,可通过队列、预设和监视文件夹批量完成格式转换、代理文件创建及多平台成片输出,并与 Premiere Pro、After Effects 等软件紧密协作。

Adobe Photoshop macOS版
Adobe Photoshop macOS版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理软件,提供图层、蒙版、选区、修复、调色、文字排版、智能对象及生成式编辑等能力。Mac 版支持 Intel 与 Apple Silicon 处理器。

WINDOWS 更多
Adobe Photoshop Windows版
Adobe Photoshop Windows版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理工具,可在 Windows 上完成照片修饰、选区抠图、图层合成、文字排版、绘画及生成式编辑。软件采用订阅授权,由 Creative Cloud 管理安装、更新与许

Adobe InDesign Windows版
Adobe InDesign Windows版

Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator

Adobe Illustrator Windows版
Adobe Illustrator Windows版

Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。

Adobe Bridge Windows版
Adobe Bridge Windows版

Adobe Bridge 是 Adobe 推出的创意资产管理工具,可集中预览、分类和查找照片、视频、PDF及多种设计文件,并支持元数据、关键词、评级、批量重命名和格式导出。它可与 Photoshop、Illustrator 等应用衔接,

Affinity Photo Windows版
Affinity Photo Windows版

Affinity Photo 是一款面向摄影师、修图师和视觉设计人员的桌面图像编辑工具,提供 RAW 显影、多图层合成、蒙版、实时滤镜、批处理和色彩管理等功能。原独立产品已停止销售,其照片编辑能力已延续至免费的新 Affinity 应用;

Adobe Lightroom Classic Windows版
Adobe Lightroom Classic Windows版

Adobe Lightroom Classic 是面向 Windows 桌面摄影工作流的照片管理与无损编辑工具,可通过目录集中整理大型图库,并完成 RAW 显影、局部蒙版、批量调整、打印和多格式导出。它强调本地文件管理与精细控制,

Figma Windows版
Figma Windows版

Figma 是面向产品设计与开发团队的云端协作平台,可在 Windows 桌面客户端中完成界面绘制、组件管理、交互原型、评论评审和开发交付。文件保存在云端,多名成员能够同步编辑并共享设计系统;官方同时提供免费 Starter 方案及按席位计

Affinity Designer Windows版
Affinity Designer Windows版

Affinity Designer 是面向矢量图形、数字插画和界面设计的专业创作工具,可在矢量、像素与导出工作区之间快速切换。它提供曲线编辑、形状构建、画板、排版、图层和专业色彩管理,并支持常见设计文件的导入及多种印刷、网页格式输出。

Capture One Pro Windows版
Capture One Pro Windows版

Capture One Pro 是面向摄影师和影像团队的专业桌面照片处理工具,提供相机定制色彩配置、RAW转换、图层与蒙版、联机拍摄、目录及会话管理等功能。它适合棚拍、人像、商业产品、婚礼和风光摄影,

Adobe Acrobat Pro Windows版
Adobe Acrobat Pro Windows版

Adobe Acrobat Pro 是面向专业 PDF 工作的综合解决方案,可在 Windows 中创建、编辑、转换、比较、整理和保护文档,并支持表单、电子签名、扫描件文字识别及敏感信息永久遮盖。订阅还包含网页、移动服务和云端协作能力,

Adobe After Effects Windows版
Adobe After Effects Windows版

Adobe After Effects 是面向动态图形、动画与影视视觉特效制作的专业工具,可完成关键帧动画、图层合成、遮罩跟踪、抠像、文字动画和二维三维元素整合。Windows 版通过 Adobe Creative Cloud 安装及更新,

DaVinci Resolve Windows版
DaVinci Resolve Windows版

DaVinci Resolve是Blackmagic Design推出的一体化影视后期工具,将素材管理、非线性剪辑、专业调色、Fusion视觉特效、Fairlight音频处理和成片交付整合在统一工程中。免费版已覆盖多数个人创作需求,