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

如何在不修改源码时动态替换导入模块中函数的Python内置函数用于测试?

针对遗留Python模块特定函数模拟内置函数的解决方案

核心思路

Python中每个模块都拥有独立的__builtins__命名空间,模块内定义的函数在调用print()、len()等内置函数时,实际是从该模块的__builtins__中查找对应的实现。因此,我们可以通过unittest.mock.patch精准替换目标模块__builtins__下的指定内置函数,仅影响该模块内的函数调用,不会产生全局副作用。

实现示例

假设遗留模块文件名为legacy_module.py,内容如下:

def legacy_function():
    print("This is a legacy function")
    return len([1, 2, 3])

对应的测试代码如下:

from unittest.mock import patch, MagicMock
import legacy_module

def test_legacy_function():
    # 同时模拟目标模块中的print和len
    with patch('legacy_module.__builtins__.print') as mock_print, \
         patch('legacy_module.__builtins__.len') as mock_len:
        # 自定义len的返回值
        mock_len.return_value = 99
        
        # 调用待测试的遗留函数
        result = legacy_module.legacy_function()
        
        # 验证print的调用情况
        mock_print.assert_called_once_with("This is a legacy function")
        # 验证len的调用参数
        mock_len.assert_called_once_with([1, 2, 3])
        # 验证函数返回值为模拟的结果
        assert result == 99

关键说明

  • 替换的目标是legacy_module.__builtins__.print而非全局的builtins.print,这样只会影响legacy_module模块内的函数对内置函数的调用,其他模块或全局代码不受影响。
  • 使用with语句包裹patch,可以确保模拟在测试结束后自动恢复,避免残留副作用。
  • 可以单独模拟某一个内置函数(比如只替换print),根据测试需求灵活调整。

注意事项

  • 若遗留模块中存在导入其他模块的情况,仅替换目标模块的__builtins__不会影响其他导入模块的内置函数调用。
  • 对于Python 2.x,模块的内置函数存放在__builtin__(单数)模块中,此时需要将替换目标改为legacy_module.__builtin__.print(注意拼写差异)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:03:23