讲师中心 微信公众号
AI工具推荐 视频效率加速

Python怎么对第三方库进行猴子补丁修改_运行时动态替换属性方法

夜宇小哥_4171

夜宇小哥_4171

发布时间:2026-04-20 21:29:10

|

611人浏览过

|

来源于php中文网

原创

猴子补丁能改requests.get,但必须在目标被导入和调用前替换模块级函数;需用functools.wraps保留原函数元信息;测试应优先用unittest.mock.patch自动管理生命周期。

python怎么对第三方库进行猴子补丁修改_运行时动态替换属性方法

什么是猴子补丁,它真能改第三方库的 requests.get 吗?

能,但得看改的是不是实例方法、类方法还是模块级函数,且必须在目标代码被导入和调用前完成替换。猴子补丁本质是直接给对象(模块、类、实例)的属性赋新值,Python 的动态性允许这么做,但它不修改源码,只影响当前解释器运行时的行为。

常见误判点:import requests 后立刻 patch requests.get 是有效的;但如果已有其他模块先导入了 requests 并缓存了旧引用(比如通过 from requests import get),那 patch 就失效了——因为那个 get 是独立绑定的函数名,不再指向 requests.get。

  • 优先 patch 模块级函数(如 requests.get、json.loads),最稳定
  • 避免 patch 类的实例方法(如 requests.Session.request)后又创建新实例——老实例不受影响,新实例才走新逻辑
  • patch 必须早于任何依赖该行为的代码执行,推荐放在 main() 开头或测试 setup 阶段

怎么安全地 patch 一个函数并保留原功能?

直接赋值会丢失原函数的签名、文档和装饰器元信息,导致 IDE 提示异常、help() 失效,甚至某些框架(如 FastAPI)路由注册失败。正确做法是用 functools.wraps 包装新函数。

import requests
from functools import wraps

original_get = requests.get

@wraps(original_get)
def patched_get(*args, **kwargs):
    print(f"[DEBUG] requests.get called with {args}")
    return original_get(*args, **kwargs)

requests.get = patched_get

注意:不能写成 requests.get = lambda *a, **k: ...,那样会丢掉 __name__ 和 __doc__,很多工具链依赖这些属性。

立即学习“Python免费学习笔记(深入)”;

python-parallelization
python-parallelization

将顺序 Python 代码转换为并行/并发实现,用于在需要并行化 Python 代码、提升性能时使用。

下载
  • 务必先保存原函数引用,再赋新值,否则 patch 后无法调用原逻辑
  • 如果原函数带类型注解(如 def get(url: str, ...) -> Response:),@wraps 会一并保留
  • 不要在 patch 函数里做耗时操作(如日志写磁盘),否则拖慢所有 requests.get 调用

patch 类方法时为什么新创建的实例不生效?

因为类方法绑定发生在实例化时。如果你 patch 的是 requests.Session.request,那么 patch 前已创建的 Session 实例,其内部仍持有对原方法的引用;只有 patch 后新建的实例,才会通过类查找机制拿到新方法。

更隐蔽的问题:有些库(如 aiohttp)会在类定义时把方法绑定到实例属性(self._request = self._request_impl),这种情况下 patch 类方法完全无效,必须 patch 实例自身的属性,或者改构造逻辑。

  • 验证是否生效:打印 session.request.__func__ is 新函数,而不是只看 session.request 的 __name__
  • 若需影响已有实例,得遍历所有活跃实例手动重绑(不推荐,易漏且难维护)
  • 真正需要改行为时,优先考虑子类继承 + 重写,比 patch 更清晰可控

测试中用 unittest.mock.patch 还是手动赋值?

测试场景下,无条件选 unittest.mock.patch。它自动处理 patch/restore 生命周期,避免测试间污染;支持装饰器、上下文管理器、类级 patch 等多种作用域控制;还能断言调用次数、参数等。

from unittest.mock import patch
import requests

def test_api_call():
    with patch("requests.get") as mock_get:
        mock_get.return_value.status_code = 200
        result = fetch_user(123)
        assert result["id"] == 123
        mock_get.assert_called_once_with("https://api.example.com/users/123")

手动赋值适合调试、临时绕过限制或非测试环境(如开发期加调试日志),但必须自己确保恢复,否则可能影响后续逻辑。

  • patch("requests.get") 中的字符串路径必须是目标对象**被使用的位置**,不是定义位置(即 "requests" 模块名,不是 "requests.api.get")
  • mock 对象默认返回 MagicMock,若需返回真实对象(如 Response 实例),要用 return_value=real_obj
  • 全局 patch(如 @patch("requests.post"))要小心,容易让多个测试相互干扰
猴子补丁不是黑魔法,它是把双刃剑:简单粗暴,但破坏封装、难以追踪、容易在升级依赖后突然失效。真正需要长期修改行为时,应该优先考虑配置开关、钩子函数、依赖注入或官方插件机制——补丁只该是临时止血,不是手术方案。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1711

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

4364

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1689

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

25497

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3107

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3127

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1163

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

596

2023.08.10

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

80

2026.10.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn