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

Python中Quantity类__lt__运算符重载异常问题求助

解决Quantity类比较运算符重载的问题

首先,咱们先拆解你代码里的两个核心问题:

1. __lt__方法的逻辑完全写反了

你当前的__lt__实现里:

  • 和另一个Quantity实例比较时,返回other.value < self.value——这其实是大于的逻辑(等同于self > other),完全不符合“小于”的预期。
  • 和numbers.Real类型比较时,返回self.value > other——同样搞反了,这是判断self大于目标数值,而非小于。

这直接导致你的<和>判断完全错乱。

2. 未处理反向比较场景

当你执行Quantity(1.2) > 1时,Python会先尝试调用Quantity的__gt__方法,但你没实现这个方法,所以Python会自动转换为反向比较:1 < Quantity(1.2)。此时int类型的__lt__不知道如何处理Quantity实例,就会尝试调用Quantity的__rlt__(反向小于)方法,如果这个方法没实现,就会抛出类型不支持的错误。


正确实现方案

方案一:手动修正逻辑并补充反向方法

先把__lt__的逻辑改对,再实现__rlt__处理反向比较:

import numbers

class Quantity:
    def __init__(self, value):
        self.value = float(value)
    
    def __float__(self):
        return self.value
    
    def __repr__(self):
        return 'Quantity({})'.format(self.value)
    
    def __str__(self):
        return str(self.value)
    
    def __lt__(self, other):
        if isinstance(other, Quantity):
            return self.value < other.value  # 修正:判断self的值小于other的值
        if isinstance(other, numbers.Real):
            return self.value < other  # 修正:判断self的值小于目标数值
        raise NotImplementedError("Unsupported comparison type")
    
    def __rlt__(self, other):
        # 处理反向比较:比如 other < self(other为numbers.Real类型)
        if isinstance(other, numbers.Real):
            return other < self.value
        raise NotImplementedError("Unsupported reverse comparison type")
    
    @property
    def value(self):
        return self._value
    
    @value.setter
    def value(self, value):
        value = round(value, 10)
        self._value = int(value * 1000) / 1000.0

修改后测试:

>>> Quantity(1.2) < 1
False
>>> Quantity(1.2) > 1
True
>>> Quantity(1.2) < Quantity(2.0)
True

方案二:用functools.total_ordering自动生成所有比较运算符

如果需要支持<、>、<=、>=、==、!=全量比较,手动写每个方法太繁琐,可以用functools.total_ordering装饰器,只需实现__lt__和__eq__,其他运算符会自动生成,同时补充反向方法处理跨类型比较:

import numbers
from functools import total_ordering

@total_ordering
class Quantity:
    def __init__(self, value):
        self.value = float(value)
    
    def __float__(self):
        return self.value
    
    def __repr__(self):
        return 'Quantity({})'.format(self.value)
    
    def __str__(self):
        return str(self.value)
    
    def __lt__(self, other):
        if isinstance(other, Quantity):
            return self.value < other.value
        if isinstance(other, numbers.Real):
            return self.value < other
        raise NotImplementedError("Unsupported comparison type")
    
    def __eq__(self, other):
        if isinstance(other, Quantity):
            return self.value == other.value
        if isinstance(other, numbers.Real):
            return self.value == other
        return False
    
    def __rlt__(self, other):
        if isinstance(other, numbers.Real):
            return other < self.value
        raise NotImplementedError("Unsupported reverse comparison type")
    
    def __req__(self, other):
        if isinstance(other, numbers.Real):
            return other == self.value
        return False
    
    @property
    def value(self):
        return self._value
    
    @value.setter
    def value(self, value):
        value = round(value, 10)
        self._value = int(value * 1000) / 1000.0

这个方案更简洁,能覆盖所有比较场景,跨类型的<、>、==都能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:18:14