自定义int类型比较器递归错误原因及类型转换必要性探究
为什么继承int的自定义类重写__lt__时必须做类型转换才不会触发递归?
问题背景
定义继承自int的类c时,重写小于比较方法__lt__会出现两种截然不同的结果:直接用self < other会触发递归错误,将self和other转为原生int后则正常运行。即便传入的是原生int类型元素,依然需要转换才能避免问题,这背后是Python的方法查找机制在起作用。
触发递归错误的代码
# Recursion Error class c(int): def __lt__(self, other): return self < other
正常运行的代码
# Working fine class c(int): def __lt__(self, other): return int(self) < int(other)
用户的使用示例:
a = [2, 1] sorted(map(int, a), key = c)
核心原因解析
- 递归触发的逻辑:当你在自定义的
__lt__方法里写self < other时,Python会优先调用当前类c的__lt__方法——因为self是c的实例,而不是原生int对象。这就导致方法内部又调用了自身,形成无限递归,最终栈溢出抛出RecursionError。 - 类型转换的作用:
int(self)会把c的实例转换成原生int对象,此时再用<比较,调用的是原生int类的__lt__方法,完全绕过了自定义的方法,自然不会产生递归。 - 关于传入参数的误解:虽然你传入的是原生
int类型,但key=c会让sorted对每个元素执行c()构造,把原生int转换成c类的实例。所以在__lt__方法里的self本质是c的实例,不是原生int,直接用<必然触发自定义方法的递归调用。
内容的提问来源于stack exchange,提问作者Andrew K
相关产品推荐
相关产品推荐

