Python __ne__() 语法
__ne__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),它用于定义当两个对象进行 “不相等(!=)” 比较时,如何判断它们的大小。
当我们使用 “!=” 运算符比较两个对象时,Python 内部会自动调用它们的 __ne__() 方法。通常情况下,我们无需显式实现 __ne__()。因为如果只定义了 __eq__(),Python 会自动推断 a != b 的行为等同于 not (a == b)。
然而,在某些特殊场景下,我们可能需要自定义 __ne__() 的行为,使其与 __eq__() 的逻辑互补或存在特定的非对称关系。
语法:
class MyObject:
def __ne__(self, other):
# 返回 True, False 或 NotImplemented
return self.value != other.value
说明:
__ne__() 方法接收以下 2 个参数。
self(必选):表示调用 “!=” 运算符的左侧对象。other(必选):表示调用 “!=” 运算符的右侧对象。
对于 __ne__() 方法,小伙伴们要清楚以下几点。
- 如果一个类只定义了 __eq__() 方法,而没有定义 __ne__() 方法。那么当使用 “!=” 运算符时,Python 会自动返回 not (self == other) 的结果。这是最常见且最为推荐的做法。
- 如果一个类既没有定义 __eq__() 也没有定义 __ne__(),那么 “!=” 运算符的默认行为是 not (self is other),也就是检查两个对象是否是不同的内存引用。
- 为了确保比较操作的一致性,通常建议在实现 __ne__() 时,也实现 __eq__()。
提示:我们可以借助 functools.total_ordering 装饰器来自动实现其他比较方法。它只需要你实现 __eq__() 和任意一个方法,就可以自动生成所有其他比较方法。
Python __ne__() 摘要
| 属于 | Python 魔法方法 |
|---|---|
| 使用频率 | 中 |
| 官方文档 | 查看 |
| 相关方法 | __eq__()、__hash__() |
Python __ne__() 示例
接下来,我们通过几个简单的例子来讲解一下 Python __ne__() 方法是如何使用的。
示例 1:__ne__() 基本用法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __ne__(self, other):
if not isinstance(other, Person):
return NotImplemented
# 当姓名或年龄不同时,视为不相等
return self.name != other.name or self.age != other.age
def __repr__(self):
return f'Person(name=\'{self.name}\', age={self.age})'
# 创建 Person 类的实例
p1 = Person('Jack', 20)
p2 = Person('Lucy', 25)
p3 = Person('Jack', 20)
p4 = Person('Jack', 21)
# 使用 != 运算符进行比较
print(p1 != p2)
print(p1 != p3)
print(p1 != p4)
运行结果如下。
True
False
True
分析:
在这个例子中,我们定义了一个 Person 类,并为其实现了 __ne__() 方法。只要两个 Person 对象的 name 或 age 属性中至少有一个不相同,它们就会被视为不相等。
- p1 != p2 返回 True,因为它们的名字和年龄都不同。
- p1 != p3 返回 False,因为它们的名字和年龄都相同。
- p1 != p4 返回 True,因为它们的年龄不同。
示例 2:__ne__() 与 __eq__() 配合使用
class Item:
def __init__(self, item_id, value):
self.item_id = item_id
self.value = value
def __eq__(self, other):
if not isinstance(other, Item):
return NotImplemented
return self.item_id == other.item_id and self.value == other.value
def __ne__(self, other):
# 显式实现 __ne__(), 往往是 __eq__() 的反面
if not isinstance(other, Item):
return NotImplemented
return self.item_id != other.item_id or self.value != other.value
def __repr__(self):
return f'Item(id={self.item_id}, value={self.value})'
# 创建 Item 类的实例
item1 = Item(101, 'Apple')
item2 = Item(102, 'Banana')
item3 = Item(101, 'Apple')
item4 = Item(101, 'Cherry')
# 使用 != 运算符
print(item1 != item2) # True
print(item1 != item3) # False
print(item1 != item4) # True
# 也可以同时验证 == 运算符
print(item1 == item3) # True
print(item1 == item4) # False
运行结果如下。
True
False
True
True
False
分析:
在 Item 类中,我们同时实现了 __eq__() 和 __ne__()。其中,__eq__() 用于定义两个 Item 相等的条件(id 和 value 都相同),而 __ne__() 用于定义不相等的条件(id 或 value 任意一个不同)。这两个方法相互补充,从而确保了比较逻辑的完整性和正确性。
示例 3:没有实现 __ne__() 方法
class MyObject:
def __init__(self, val):
self.val = val
def __eq__(self, other):
if not isinstance(other, MyObject):
return NotImplemented
return self.val == other.val
def __repr__(self):
return f'MyObject({self.val})'
# 创建实例
obj1 = MyObject(10)
obj2 = MyObject(20)
obj3 = MyObject(10)
# 即使没有定义 __ne__(),!= 也会正常工作
print(obj1 != obj2)
print(obj1 != obj3)
print(obj1 == obj3)
运行结果如下。
True
False
True
分析:
如果一个类只定义了 __eq__() 方法而没有定义 __ne__() 方法,Python 会自动推断 __ne__() 的行为,使其返回 __eq__() 结果的逻辑非。
