Python __le__() 语法
__le__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),它用于定义当两个对象进行 “小于等于(<=)” 比较时,如何判断它们的大小。
当我们使用 “<=” 运算符比较两个对象时,Python 内部会自动调用它们的 __le__() 方法。
语法:
class MyObject:
def __le__(self, other):
# 返回 True, False 或 NotImplemented
return self.value <= other.value
说明:
__le__() 方法接收以下 2 个参数。
self(必选):表示调用 “<=” 运算符的左侧对象。other(必选):表示调用 “<=” 运算符的右侧对象。
__le__() 方法必须返回一个布尔值(True 或 False),用于表示比较的结果。如果不支持比较(比如类型不兼容),则应返回 NotImplemented。如果返回 NotImplemented,Python 可能会尝试调用 other 对象的 __gt__() 方法来尝试反向比较。
为了确保比较操作的一致性,我们通常建议在实现 __le__() 时,也实现其他比较方法,如 __lt__()、__eq__()、__ne__()、__gt__() 和 __ge__() 等。
提示:我们可以借助 functools.total_ordering 装饰器来自动实现其他比较方法。它只需要你实现 __eq__() 和任意一个方法,就可以自动生成所有其他比较方法。
Python __le__() 摘要
| 属于 | Python 魔法方法 |
|---|---|
| 使用频率 | 中 |
| 官方文档 | 查看 |
| 相关方法 | __lt__()、__eq__()、__ne__()、__gt__()、__ge__() |
Python __le__() 示例
接下来,我们通过几个简单的例子来讲解一下 Python __le__() 方法是如何使用的。
示例 1:__le__() 基本用法
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
def __le__(self, other):
if isinstance(other, Temperature):
return self.celsius <= other.celsius
elif isinstance(other, (int, float)):
return self.celsius <= other
return NotImplemented
# 创建实例
temp1 = Temperature(25)
temp2 = Temperature(30)
temp3 = Temperature(25)
# 使用 <= 运算符进行比较
print(temp1 <= temp2)
print(temp2 <= temp1)
print(temp1 <= temp3)
运行结果如下。
True
False
True
分析:
在这个例子中,我们定义了一个 Temperature 类,并为其实现了 __le__() 方法。当比较两个 Temperature 对象时,该方法比较它们内部的 celsius 属性。
示例 2:__le__() 比较不同类型的对象
class Distance:
def __init__(self, meters):
self.meters = meters
def __le__(self, other):
if isinstance(other, Distance):
return self.meters <= other.meters
elif isinstance(other, (int, float)):
# 允许与数字(表示米)直接比较
return self.meters <= other
return NotImplemented # 如果类型不兼容,返回 NotImplemented
# 创建实例
d1 = Distance(100)
# 与整数比较
print(d1 <= 100)
print(d1 <= 90)
# 与浮点数比较
print(d1 <= 100.0)
运行结果如下。
True
False
True
分析:
在 Distance 类中,我们手动实现了 __le__() 方法。该方法支持两个 Distance 对象进行比较,或者一个 Distance 对象与 int、float 值进行比较。例如,d1 <= 100 比较的是 d1.meters (100) 是否小于等于 100,因此返回结果为 True。
示例 3:__le__() 结合 functools.total_ordering
import functools
@functools.total_ordering
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
def __eq__(self, other):
if not isinstance(other, Item):
return NotImplemented
return self.price == other.price
def __le__(self, other):
if not isinstance(other, Item):
return NotImplemented
return self.price <= other.price
def __repr__(self):
return f'Item({self.name}, {self.price})'
# 创建实例
item1 = Item('小米手机', 3000)
item2 = Item('一加手机', 2000)
item3 = Item('华为手机', 3000)
# 使用 <= 运算符
print(item1 <= item2) # False
print(item2 <= item1) # True
print(item1 <= item3) # True
# 由于 @total_ordering,其他比较运算符也可用
print(item1 >= item2) # True
print(item1 < item3) # False (1200不小于1200)
运行结果如下。
False
True
True
True
False
分析:
通过使用 @functools.total_ordering 装饰器,我们只需要实现了 __eq__() 和 __le__() 这两个方法,然后其他的比较运算符(如 >=, <)的行为都会由 total_ordering 自动推导出来。
