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

如何让Python的assert断言显示失败的实际值?纯Python实现

在Python中增强assert断言,显示实际值的方法

当然可以通过纯Python实现,让断言失败时自动展示预期值和实际值,不用每次手动拼接错误信息。

方法1:自定义断言函数(简单直接)

写一个封装好的断言函数,专门处理常见的检查场景(类似gtest的EXPECT_EQ),失败时自动输出预期和实际值:

def assert_eq(expected, actual, msg=None):
    if expected != actual:
        error_msg = f"Assertion failed: expected {repr(expected)}, actual {repr(actual)}"
        if msg:
            error_msg += f" ({msg})"
        raise AssertionError(error_msg)

def assert_gt(expected, actual, msg=None):
    if not actual > expected:
        error_msg = f"Assertion failed: expected actual > {repr(expected)}, got {repr(actual)}"
        if msg:
            error_msg += f" ({msg})"
        raise AssertionError(error_msg)

使用示例:

my_list = [1, 2]
assert_eq(3, len(my_list))

失败时输出:

AssertionError: Assertion failed: expected 3, actual 2

你可以根据需求扩展出assert_lt(小于)、assert_in(包含)等更多断言类型,覆盖不同场景。

方法2:自动解析断言表达式(更接近gtest体验)

利用inspect模块获取调用栈和断言表达式,自动解析出左右两边的实际值,写法更贴近原生assert:

import inspect

def assert_check(expr):
    caller_frame = inspect.currentframe().f_back
    # 提取调用行的断言表达式字符串
    line = inspect.getsource(caller_frame).strip()
    expr_str = line.split('assert_check(')[1].rstrip(') \n;')
    
    try:
        if not eval(expr, caller_frame.f_globals, caller_frame.f_locals):
            # 处理常见比较操作符
            ops_map = {
                '==': ('Expected', 'Actual'),
                '!=': ('Unexpected', 'Actual'),
                '>': ('Expected greater than', 'Actual'),
                '<': ('Expected less than', 'Actual')
            }
            for op, (desc1, desc2) in ops_map.items():
                if op in expr_str:
                    left_part, right_part = expr_str.split(op, 1)
                    left_val = eval(left_part.strip(), caller_frame.f_globals, caller_frame.f_locals)
                    right_val = eval(right_part.strip(), caller_frame.f_globals, caller_frame.f_locals)
                    raise AssertionError(
                        f"Assertion failed: {expr_str}\n{desc1}: {repr(right_val)}\n{desc2}: {repr(left_val)}"
                    )
            # 未匹配到操作符的通用情况
            raise AssertionError(f"Assertion failed: {expr_str}")
    except Exception as e:
        raise AssertionError(f"Failed to evaluate assertion: {expr_str}") from e

使用示例:

my_num = 7
assert_check(my_num < 5)

失败时输出:

AssertionError: Assertion failed: my_num < 5
Expected less than: 5
Actual: 7

这种方法的优势是不用手动拆分预期和实际值,但对复杂表达式(比如带逻辑运算符and/or的)解析可能不准确,可根据需求扩展解析逻辑。

注意事项

  • 不建议修改全局assert语句的行为(比如修改__builtins__),会影响整个代码环境,自定义函数是更安全的选择。
  • 如果需要和原生assert保持一致(-O模式下禁用),可以在自定义函数开头添加if not __debug__: return。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:45:05