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

如何使用mock.patch将函数替换为带自定义参数的自身且不触发递归

解决方案

问题根因

你之前的写法触发递归的核心原因是:patch生效后,mymodule.myfunction已经被替换为你写的lambda函数,lambda内部再调用mymodule.myfunction实际是调用自身,自然会触发栈溢出。


方案1:提前保存原始函数引用(最通用)

在patch还未生效的模块导入阶段,先把原始函数的引用存到独立变量中,patch后的回调直接调用这个原始引用即可规避递归,搭配functools.partial可以更简洁地绑定参数:

import unittest
from unittest.mock import patch
from functools import partial

import mymodule
import production

# 模块加载时就保存未被patch的原始函数引用
original_myfunction = mymodule.myfunction

class MyTest(unittest.TestCase):
    @patch('production.mymodule.myfunction', new=partial(original_myfunction, devmode=True))
    def test_main_with_mymodule_function_does_not_raise_exception(self):
        # 这是一个集成测试,myfunction在main内部被调用
        try:
            production.main()
        except Exception as e:
            self.fail(e)

方案2:直接修改函数默认参数(更轻量,无需mock)

如果你的需求只是修改devmode的默认值,完全不需要用mock替换函数,直接修改函数的默认参数元组即可:

import unittest

import mymodule
import production

class MyTest(unittest.TestCase):
    def test_main_with_mymodule_function_does_not_raise_exception(self):
        # 保存原有默认参数
        origin_defaults = mymodule.myfunction.__defaults__
        # 假设devmode是函数最后一个位置参数,默认值为False,替换为True
        new_defaults = list(origin_defaults)
        new_defaults[-1] = True
        mymodule.myfunction.__defaults__ = tuple(new_defaults)

        try:
            production.main()
        except Exception as e:
            self.fail(e)
        finally:
            # 测试结束后恢复原有默认参数,避免影响其他用例
            mymodule.myfunction.__defaults__ = origin_defaults

注意:如果devmode是关键字-only参数(即定义在*之后),需要修改的是mymodule.myfunction.__kwdefaults__字典而非__defaults__。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 20:36:04