ZetCode

Python __gt__ 方法

最后修改于 2025 年 4 月 8 日

本篇综合指南探讨了 Python 的 __gt__ 方法,这是一个实现大于运算符的特殊方法。我们将介绍基本用法、比较操作、运算符重载和实际示例。

基本定义

__gt__ 方法是一个特殊方法,它在 Python 中实现“大于”运算符 (>)。它允许对象定义在使用 > 运算符时自己的比较行为。

主要特点:它接受两个参数 (selfother),返回一个布尔值,并且对于不支持的比较应该返回 NotImplemented。它是 Python 丰富比较方法的一部分。

基本 __gt__ 实现

这是一个简单的实现,展示了 __gt__ 如何与自定义类一起工作。此示例根据属性值比较对象。

basic_gt.py
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price
    
    def __gt__(self, other):
        if not isinstance(other, Product):
            return NotImplemented
        return self.price > other.price

p1 = Product("Laptop", 999)
p2 = Product("Phone", 699)
print(p1 > p2)  # True

此示例基于价格属性比较 Product 实例。如果当前实例的价格大于另一个实例的价格,则 __gt__ 方法返回 True

NotImplemented 返回值指示何时尝试与不支持的类型进行比较,从而允许 Python 尝试反向操作。

比较不同类型

__gt__ 可以处理不同类型之间的比较,但对于不支持的类型,最好返回 NotImplemented

different_types.py
class Distance:
    def __init__(self, meters):
        self.meters = meters
    
    def __gt__(self, other):
        if isinstance(other, Distance):
            return self.meters > other.meters
        elif isinstance(other, (int, float)):
            return self.meters > other
        return NotImplemented

d1 = Distance(100)
print(d1 > Distance(50))  # True
print(d1 > 75)            # True
print(d1 > "100")         # TypeError

这个 Distance 类可以与其他 Distance 对象或数字进行比较。当与不支持的类型(如字符串)进行比较时,它返回 NotImplemented,从而导致 TypeError

该方法首先检查 other 的类型,然后再执行比较,使其更灵活,同时保持类型安全。

使用 __lt__ 进行反向比较

__gt__ 返回 NotImplemented 时,Python 会尝试使用另一个对象的 __lt__ 方法进行反向操作。

reverse_comparison.py
class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius
    
    def __gt__(self, other):
        if isinstance(other, Temperature):
            return self.celsius > other.celsius
        return NotImplemented
    
    def __lt__(self, other):
        if isinstance(other, (int, float)):
            return self.celsius < other
        return NotImplemented

t = Temperature(25)
print(t > Temperature(20))  # True (uses __gt__)
print(30 > t)               # True (uses __lt__)

此示例显示了当未为特定比较实现 __gt__ 时,Python 如何回退到 __lt__30 > t 表达式使用 t.__lt__(30)

实现这两种方法提供了更灵活的比较行为,同时保持操作之间的一致性。

继承和 __gt__

使用继承时,可以覆盖 __gt__ 以修改子类中的比较行为,同时保持父类的功能。

inheritance.py
class Animal:
    def __init__(self, weight):
        self.weight = weight
    
    def __gt__(self, other):
        if not isinstance(other, Animal):
            return NotImplemented
        return self.weight > other.weight

class Dog(Animal):
    def __gt__(self, other):
        if isinstance(other, Dog):
            return self.weight * 2 > other.weight * 2
        return super().__gt__(other)

a1 = Animal(10)
a2 = Animal(15)
d1 = Dog(5)
d2 = Dog(8)

print(a1 > a2)  # False
print(d1 > d2)  # False (but compares 10 vs 16)
print(d1 > a1)  # False (uses Animal.__gt__)

当比较两个 Dog 实例时,Dog 类修改比较行为,但对于其他比较,它会回退到父类的 __gt__

这种模式允许专门的比较逻辑,同时保持与父类和其他类型的一致行为。

使用 functools 进行完全排序

如果至少定义了一个比较方法(例如 __gt__)和 __eq__,则 functools.total_ordering 装饰器可以生成缺少的比较方法。

total_ordering.py
from functools import total_ordering

@total_ordering
class Score:
    def __init__(self, points):
        self.points = points
    
    def __gt__(self, other):
        if not isinstance(other, Score):
            return NotImplemented
        return self.points > other.points
    
    def __eq__(self, other):
        if not isinstance(other, Score):
            return NotImplemented
        return self.points == other.points

s1 = Score(85)
s2 = Score(90)
print(s1 > s2)   # False
print(s1 <= s2)  # True (generated by total_ordering)

仅定义了 __gt____eq__,装饰器就提供了所有其他比较方法(__lt____le__ 等)。这减少了样板代码。

生成的方法保持与已定义比较的一致行为,确保所有操作都按照基于两个已实现方法的预期方式工作。

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。到目前为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程