You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用contextlib.suppress替代嵌套try/else时遇UnboundLocalError的解决方法

用contextlib.suppress替代嵌套try/except的正确姿势

为遵循flake8规范,尝试用contextlib.suppress替代嵌套try/except结构获取模型的early_stopping_rounds(早停轮数),但改写后出现UnboundLocalError: local variable 'n_rounds' referenced before assignment错误,以下是问题分析和正确用法:

原函数(可正常工作)

def _get_early_stopping_rounds(model, **kwargs) -> int:
    """Returns the number of early stopping rounds."""
    try:
        n_rounds = kwargs["early_stopping_rounds"]
    except Exception:
        try:
            n_rounds = model.get_params()["early_stopping_rounds"]
        except Exception:
            try:
                n_rounds = None
            except Exception:
                pass

    return n_rounds

该函数优先从kwargs中取值,失败则尝试从model.get_params()获取,仍失败则返回None,示例调用返回20。

错误的改写版本

from contextlib import suppress

def _get_early_stopping_rounds(model, **kwargs) -> int:
    """Returns the number of early stopping rounds."""
    with suppress(Exception):
        n_rounds = kwargs["early_stopping_rounds"]
        with suppress(Exception):
            n_rounds = model.get_params()["early_stopping_rounds"]
            with suppress(Exception):
                n_rounds = None
    return n_rounds

错误原因

  • 嵌套的with suppress是串行执行:只有前一个赋值成功,才会进入下一个with块;如果所有赋值操作都触发异常,n_rounds从未被定义,返回时就会抛出未绑定变量的错误。
  • 原函数的第三个try完全多余,因为n_rounds = None不会抛出任何异常。

正确的改写方式

先给n_rounds设置默认值,再用独立的with suppress依次尝试不同的赋值来源,逻辑和原函数一致:

from contextlib import suppress

def _get_early_stopping_rounds(model, **kwargs) -> int:
    """Returns the number of early stopping rounds."""
    n_rounds = None  # 初始化默认值,避免未绑定错误
    # 优先尝试从kwargs获取
    with suppress(Exception):
        n_rounds = kwargs["early_stopping_rounds"]
    # kwargs获取失败时,尝试从model参数中获取
    with suppress(Exception):
        n_rounds = model.get_params()["early_stopping_rounds"]
    return n_rounds

逻辑说明

  • 先初始化n_rounds为None,确保无论后续操作是否成功,变量都已绑定。
  • 每个with suppress块独立尝试一种赋值方式:如果kwargs中存在目标值,就覆盖默认值;如果失败,保持当前值(默认的None),再尝试从model.get_params()中获取,成功则覆盖,失败则保留之前的值。
  • 去掉了原函数中多余的第三个try块,因为赋值None不会触发异常。

内容的提问来源于stack exchange,提问作者Jake Niederer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:10:29