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

Python unittest.mock.patch对函数参数默认值不生效问题求解

问题成因

Python 中函数的默认参数只会在函数定义阶段求值一次,求值结果会被保存在函数的__defaults__属性中,后续调用函数时如果不传该参数,会直接复用第一次的求值结果,不会重新计算。
你定义print_a时,默认参数file=sys.stdout直接取了函数定义时真实系统标准输出的引用,后续你用@patch修改的只是sys.stdout这个变量的指向,并没有改动print_a里已经保存的旧stdout引用,因此print_a的输出还是会写到原始的标准输出里,不会被mock捕获。
而print_b没有提前缓存sys.stdout,每次调用时都会实时读取当前sys.stdout的指向,此时已经被patch替换成了mock对象,因此输出可以被正常捕获。
另外你写的@patch装饰器存在拼写错误:new_callablle多写了一个字母l,正确写法为new_callable,这个错误也会导致mock逻辑无法按预期生效。

解决方法
  • 方案1:修改print_a的参数定义,避免在函数定义阶段就求值sys.stdout:
def print_a(file=None):
    """
    调用时再获取当前的sys.stdout,可被正常mock
    """
    if file is None:
        file = sys.stdout
    print("a", file=file)
  • 方案2:如果不能修改原函数的实现,测试时主动传入当前的sys.stdout即可:
# 测试调用时主动传参
test_print(lambda: print_a(file=sys.stdout))
  • 方案3:也可以在测试时直接patch print_a的默认参数,不过这种方式侵入性更强,不推荐优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:24:08