如何在 Python 类中使用等价(“相等”)运算符?
使用比较运算符,我们可以在 Python 中比较各种数据类型。在创建自定义类时,我们无法简单地使用比较运算符来比较它们。
本文将介绍在 Python 类中验证等价性(“相等性”)的各种方法。
类对象的相等性
== 运算符可以轻松确定两个内置对象(例如字符串或整数)是否相等。这在下面的示例中进行了演示。
示例
以下是 == 运算符的示例:
char1 = 365 char2 = 83 result = char1 == char2 print("{} and {} are equivalent to each other:{}".format(char1, char2, result))
输出
以下是上述代码的输出:
365 and 83 are equivalent to each other:False
注意 - 因为数字 365 和 83 都是整数,所以 == 运算符在此例中返回正确的结果。但是,当处理来自唯一类的对象时,Python 解释器会表现出不同的行为。
示例
假设 Square 类只有一个属性 square,如下所示:
class Square: def __init__(self, area): self.square = area print ('equal')
输出
以下是上述代码的输出:
equal
现在,square 属性将在 Square 类的两个实例中设置为相同的面积。
示例
class Square: def __init__(self, area): self.square = area sq1 = Square(23) sq2 = Square(23) print ('equal')
输出
以下是上述代码的输出:
equal
注意 - 即使两个实例的 square 属性具有相同的面积,使用 == 运算符比较对象的返回值也将为 False。这在以下代码中显示:
示例
class Square: def __init__(self, area): self.square = area sq1 = Square(23) sq2 = Square(23) result = sq1 == sq2 print ('sq1 and sq2 are equal:',result)
输出
以下是上述代码的输出:
sq1 and sq2 are equal: False
注意 - 可以使用 Python 解释器如何比较来自用户定义类的两个对象来解释上述行为。当我们使用 Python 的 == 运算符比较两个类对象的相等性时,只有当两个对象都指向相同的内存地址时,结果才会为 True。
换句话说,将只有一个 Python 对象和两个变量。这在以下示例中可以看到:
示例
class Square: def __init__(self, area): self.square = area sq1 = Square(23) sq2 = sq1 result = sq1 == sq2 print ('sq1 and sq2 are equal:',result)
输出
以下是上述代码的输出:
sq1 and sq2 are equal: True
现在很清楚,只有当两个变量都引用用户定义类的同一个实例时,相等运算符才会返回 True。
使用 __eq__() 方法实现相等
通过覆盖 __eq__() 方法,我们可以调整 == 运算符相对于自定义类的行为。例如,我们可以覆盖 __eq__() 函数以比较 Square 类的两个实例的平方。
以下过程将在 __eq__() 方法中应用:
- 当在 Square 类实例上使用时,__eq__() 方法将接受一个额外的对象作为输入参数。
- 我们首先将在 __eq__() 方法内部确定输入对象是否是 Square 类的实例。在这种情况下可以使用 isinstance() 函数。
- isinstance() 函数的第一个和第二个输入参数分别是类名和 Python 对象。如果对象是执行后输入参数中指定的类的实例,则返回 True。
- 在我们的程序中,第二个输入参数将是 Square 类。如果第一个参数的对象不是 Square 类的实例,则它将返回 False。
如果不是,我们将继续,
- 我们将比较两个对象中的属性 square 面积,以确定这两个对象是否属于同一个类。如果面积相等,则结果为 True。
如果不是,我们将返回 False。
- 一旦将 __eq__() 方法添加到 Square 类,我们就可以使用 == 运算符适当地比较 Number 类的两个实例。
- 假设我们有两个 Square 类实例,我们称它们为 sq1 和 sq2。当 sq1==sq2 时,将应用 sq1.__eq__(sq2) 函数。
- 与此类似,当我们执行 sq2==sq1 时,将执行 sq2.__eq__(sq1) 方法。
- 代码执行后,如果两个对象的平方面积相等,则 sq1==sq2 将返回 True。如果不是,则返回 False。
我们可以在以下示例中观察到:
示例
class Square: def __init__(self, area): self.square = area def __eq__(self, other): isSquare = isinstance(other, self.__class__) if not isSquare: return False if self.square == other.square: return True else: return False sq1 = Square(23) sq2 = Square(23) result = sq1 == sq2 print ('sq1 and sq2 are equal:',result)
输出
以下是上述代码的输出:
sq1 and sq2 are equal: True
使用 id() 方法实现相等
此外,您可以确定具有自定义类对象的两个变量是否引用同一个对象。为此可以使用 id() 函数。
可以使用 id() 函数在内存中的任何位置找到唯一的标识号,该函数接受一个对象作为输入参数。
示例
以下是 id() 方法的示例:
class Square: def __init__(self, area): self.square = area def __eq__(self, other): isSquare = isinstance(other, self.__class__) if not isSquare: return False if self.square == other.square: return True else: return False sq1 = Square(23) sq2 = Square(23) result1 = id(sq1) result2 = id(sq2) print ('The sq1 id is:',result1) print ('The sq2 id is:',result2)
输出
以下是上述代码的输出:
The sq1 id is: 2632227365088 The sq2 id is: 2632227365232
注意 - 如果两个对象都引用同一个内存位置,则 id() 函数将对这两个对象返回相同的结果。我们可以通过比较 id() 函数的输出(如以下示例所示)来确定两个对象是否引用同一个内存地址:
示例
class Square: def __init__(self, area): self.square = area def __eq__(self, other): isSquare = isinstance(other, self.__class__) if not isSquare: return False if self.square == other.square: return True else: return False sq1 = Square(23) sq2 = Square(23) result1 = id(sq1) result2 = id(sq2) result = result1 == result2 print ('sq1 and sq2 are equal:',result2)
输出
以下是上述代码的输出:
sq1 and sq2 are equal: 2284484764016
如您所见,在这种情况下,我们没有检查对象的属性面积来确定它们是否属于同一个类。
在这种情况下,我们只是确定对象是否引用同一个内存区域。因此,在类声明中不包含 __eq__() 函数的情况下使用 == 运算符等同于使用这种确定 Python 类相等性的方法。