ZetCode

Python __ge__ 方法

最后修改于 2025 年 4 月 8 日

本综合指南探讨了 Python 的 __ge__ 方法,这是一个实现大于或等于比较运算符的特殊方法。我们将介绍基本用法、常见模式和实际示例。

基本定义

__ge__ 方法是 Python 丰富的比较方法之一。它为类实例实现 >= 运算符。该方法应返回 TrueFalse,但它可以返回任何值。

主要特征:它接受两个参数(selfother),在使用 >= 运算符时调用,并且应该实现一致的比较逻辑。它是 Python 运算符重载系统的一部分。

基本 __ge__ 实现

这是一个简单的实现,展示了 __ge__ 如何与表示距离的类一起工作。该方法比较距离值。

basic_ge.py
class Distance:
    def __init__(self, meters):
        self.meters = meters
    
    def __ge__(self, other):
        if not isinstance(other, Distance):
            return NotImplemented
        return self.meters >= other.meters

d1 = Distance(100)
d2 = Distance(50)
print(d1 >= d2)  # True
print(d2 >= d1)  # False

此示例显示了 __ge__ 的基本结构。它检查另一个对象是否为 Distance 实例,并比较它们的米值。 NotImplemented 返回允许 Python 尝试反向比较。

当当前实例的米数大于或等于另一个实例的米数时,该方法返回 True。这使得使用 >= 的自然比较语法成为可能。

比较不同类型

__ge__ 可以通过在类型不兼容时返回 NotImplemented 来处理与不同类型的比较。这允许 Python 尝试反向操作。

different_types.py
class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius
    
    def __ge__(self, other):
        if isinstance(other, Temperature):
            return self.celsius >= other.celsius
        elif isinstance(other, (int, float)):
            return self.celsius >= other
        return NotImplemented

t = Temperature(25)
print(t >= Temperature(20))  # True
print(t >= 30)               # False
print(15 >= t)               # False (uses __le__ of Temperature)

此类温度类既可以与其他 Temperature 实例进行比较,也可以与数字进行比较。 当与不兼容的类型进行比较时,它返回 NotImplemented 以允许 Python 尝试反向操作。

该示例演示了如何在保持类型安全的同时处理多个比较场景。该方法首先检查 other 的类型,然后再进行比较。

使用 functools 进行完全排序

在实现 __ge__ 时,通常也实现其他比较方法也很有用。 functools.total_ordering 装饰器可以帮助最大限度地减少样板代码。

total_ordering.py
from functools import total_ordering

@total_ordering
class Version:
    def __init__(self, major, minor):
        self.major = major
        self.minor = minor
    
    def __eq__(self, other):
        if not isinstance(other, Version):
            return False
        return (self.major, self.minor) == (other.major, other.minor)
    
    def __ge__(self, other):
        if not isinstance(other, Version):
            return NotImplemented
        return (self.major, self.minor) >= (other.major, other.minor)

v1 = Version(1, 2)
v2 = Version(1, 3)
print(v1 >= v2)  # False
print(v1 <= v2)  # True (provided by total_ordering)

这个版本类实现了 __eq____ge__,并从 total_ordering 获取所有其他比较方法。 装饰器根据这两个方法填充缺失的比较方法。

该实现按顺序比较主要和次要版本号。 元组比较确保版本组件的正确字典序排序。

反向比较处理

当左操作数未实现 __ge__ 时,Python 会尝试右操作数的 __le__。 此示例显示了如何处理此类情况。

reverse_comparison.py
class Weight:
    def __init__(self, kg):
        self.kg = kg
    
    def __ge__(self, other):
        if isinstance(other, Weight):
            return self.kg >= other.kg
        elif isinstance(other, (int, float)):
            return self.kg >= other
        return NotImplemented
    
    def __le__(self, other):
        if isinstance(other, Weight):
            return self.kg <= other.kg
        elif isinstance(other, (int, float)):
            return self.kg <= other
        return NotImplemented

w = Weight(50)
print(w >= 40)        # True (uses __ge__)
print(60 >= w)        # True (uses __le__)
print("50" >= w)      # TypeError

此权重类实现了 __ge____le__,以处理来自两侧的比较。 它保持操作之间的一致性。

当与不兼容的类型(如字符串)进行比较时,在 __ge____le__ 都返回 NotImplemented 后,Python 会引发 TypeError

继承和比较

在处理继承时,__ge__ 应该仔细处理父类和子类之间的比较,以保持 Liskov 替换原则。

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

class Dog(Animal):
    def __init__(self, weight, breed):
        super().__init__(weight)
        self.breed = breed

a = Animal(10)
d = Dog(15, "Labrador")
print(d >= a)  # True
print(a >= d)  # True (works because Dog is an Animal)

此示例显示了父类和子类之间的正确比较。 父类中的 __ge__ 方法接受任何 Animal 实例,包括其子类。

该实现仅比较 weight 属性,忽略特定于子类的属性。 这在整个继承层次结构中保持比较操作的一致性。

最佳实践

资料来源

作者

我叫 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程