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

如何重定义Python3 MagicMock魔术方法?子类重写为何返回NotImplemented?

这个问题的核心在于MagicMock对魔术方法的特殊处理机制——它并不会像普通类那样直接使用你子类中重写的魔术方法,而是会动态生成一个mock版本的方法,这就是为什么你得到NotImplemented的原因。

MagicMock的设计初衷是自动mock所有属性和方法,包括魔术方法。当你访问t1.__lt__时,它的内部拦截机制会优先创建一个默认返回NotImplemented的mock方法,完全绕过了你在子类中定义的__lt__实现。

而普通类(比如你例子中的B)没有这种动态mock的逻辑,所以子类重写的方法会被正常调用,自然能返回self。

解决方法

你可以通过两种方式让子类的魔术方法按预期工作:

方法1:在__init__中设置魔术方法的side_effect

利用MagicMock的side_effect属性,给__lt__绑定自定义逻辑:

from unittest.mock import MagicMock

class MockForTest(MagicMock):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 让__lt__调用时返回自身
        self.__lt__.side_effect = lambda: self

t1 = MockForTest()
print(t1.__lt__())  # 输出类似<__main__.MockForTest object at 0x000001D6EE77B2B0>的实例对象

方法2:覆盖__getattr__拦截魔术方法的获取

通过重写__getattr__,当获取__lt__时返回你自定义的方法,其他属性交给父类处理:

from unittest.mock import MagicMock

class MockForTest(MagicMock):
    def __getattr__(self, name):
        if name == '__lt__':
            return lambda: self
        # 其他属性继续使用MagicMock的默认逻辑
        return super().__getattr__(name)

t1 = MockForTest()
print(t1.__lt__())  # 同样返回实例对象

这两种方法都能绕过MagicMock的默认魔术方法mock逻辑,让你的自定义实现生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:56:37