如何在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类相等性的方法。