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

Python中如何对Mock对象排序?解决MagicMock排序报错问题

解决Mock对象排序报错的方法

问题原因

MagicMock会动态拦截__lt__这类特殊方法的调用,即便你继承重写了该方法,默认也不会触发自定义逻辑,导致排序时依然报错。

方案1:用普通自定义类替代MagicMock(推荐)

如果仅需模拟path的比较逻辑,无需依赖MagicMock,直接实现极简模拟类即可,借助functools.total_ordering装饰器自动生成全量比较方法:

from functools import total_ordering
import random
from typing import Optional

@total_ordering
class MockPath:
    def __init__(self, name: Optional[str] = None):
        self.name = name or str(random.randint(1, 10000))
    
    def __lt__(self, other) -> bool:
        # 排序结果不重要的话,也可以用`id(self) < id(other)`替代基于name的比较
        return self.name < other.name
    
    def __eq__(self, other) -> bool:
        return self.name == other.name

使用时直接给对象的path属性赋值该类实例:

obj1.path = MockPath("file1")
obj2.path = MockPath("file2")

方案2:给MagicMock实例手动绑定__lt__方法

如果必须使用MagicMock,直接给实例添加__lt__方法,绕过MagicMock的特殊方法拦截:

from unittest.mock import MagicMock
import random

path_mock1 = MagicMock()
path_mock1.name = str(random.randint(1, 10000))
path_mock1.__lt__ = lambda self, other: self.name < other.name

path_mock2 = MagicMock()
path_mock2.name = str(random.randint(1, 10000))
path_mock2.__lt__ = lambda self, other: self.name < other.name

obj1.path = path_mock1
obj2.path = path_mock2

方案3:修改自定义MockPath类,避免方法被覆盖

若坚持继承MagicMock,需在初始化时将自定义__lt__绑定为实例属性,防止被MagicMock的动态逻辑覆盖:

from unittest.mock import MagicMock
import random
from typing import Optional

class MockPath(MagicMock):
    def __init__(self, name: Optional[str] = None, *args, **kw):
        super().__init__(*args, **kw)
        self.name = name or str(random.randint(1, 10000))
        # 手动绑定自定义比较方法
        self.__lt__ = self._compare_lt
    
    def _compare_lt(self, other) -> bool:
        return self.name < other.name

实例化MockPath后,__lt__方法就能正常触发自定义逻辑,排序时不再报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:40:50