在 Python 中,我们可以使用比较运算符来比较不同的数据类型。 但是,我们不能在创建自定义类时简单地使用比较运算符来比较它们。
本文将讨论检查在 Python 中使用自定义类定义的对象是否相等的不同方法。
Python 中类对象的相等性
当我们有像整数或字符串这样的内置对象时,我们可以使用 == 运算符轻松检查它们是否相等,如下所示。
num1 = 12
num2 = 10
result = num1 == num2
print("{} and {} are equal:{}".format(num1, num2, result))
输出:
12 and 10 are equal:False
这里,==
运算符给出正确的值作为输出,因为值 12 和 10 是整数。 然而,当我们有自定义类的对象时,Python 解释器的工作方式不同。
例如,假设我们有一个只有一个属性 length 的 Length 类,如下所示。
class Length:
def __init__(self, value):
self.length = value
我们将在长度属性中创建具有相同值的类长度的两个实例。
class Length:
def __init__(self, value):
self.length = value
len1 = Length(10)
len2 = Length(10)
如果使用 ==
运算符比较对象,即使两个实例的长度属性值相同,结果也将为 False。 您可以在以下代码中观察到这一点。
class Length:
def __init__(self, value):
self.length = value
len1 = Length(10)
len2 = Length(10)
result = len1 == len2
print("len1 and len2 are equal:", result)
输出:
len1 and len2 are equal: False
Python 解释器的上述行为可以用它比较用户定义类的两个对象的方式来描述。 当我们在 Python 中使用 ==
运算符检查两个类对象是否相等时,只有当两个对象都引用相同的内存位置时,结果才会为 True。
换句话说,将有两个变量,但只有一个 Python 对象。 您可以在以下示例中观察到这一点。
class Length:
def __init__(self, value):
self.length = value
len1 = Length(10)
len2 = len1
result = len1 == len2
print("len1 and len2 are equal:", result)
输出:
len1 and len2 are equal: True
我们可能已经了解,仅当两个变量都引用用户定义类的同一实例时,相等运算符才会返回 True。
如果我们需要在 Python 中检查一个类的不同实例是否相等,我们应该怎么做? 让我们找出答案。
使用 __eq__()
方法的 Python 类相等性
通过覆盖 __eq__()
方法,我们可以修改 == 运算符如何与自定义类一起工作。 例如,要检查 Length 类的两个实例的长度,我们可以覆盖 __eq__()
方法。
我们将在 __eq__()
方法中使用下面讨论的步骤。
__eq__()
方法在 Length 类的实例上调用时,会将另一个对象作为其输入参数。
在 __eq__()
方法中,我们将首先检查输入对象是否是 Length 类的实例。 为此,我们可以使用 isinstance()
函数。
isinstance()
函数将 Python 对象作为其第一个输入参数,并将类名作为其第二个输入参数。 执行后,如果对象是输入参数中提供的类的实例,则返回 True。
我们将把 Length 类作为程序中的第二个输入参数传递。 如果第一个参数传入的对象不是 Length 类的实例,它将返回 False。
否则,我们将继续前进。
为了检查两个对象的类是否相等,我们将比较两个对象中的属性长度值。 如果值相等,我们将返回 True。
否则,我们将返回 False。
一旦在 Length 类中实现了 __eq__()
方法,我们就可以使用 == 运算符正确地比较 Number 类的两个实例。
假设我们有 Length 类的两个实例,比如 len1 和 len2。 当我们执行len1==len2时,就会执行 len1.__eq__(len2)
方法。
同样,当我们执行len2==len1时,就会执行 len2.__eq__(len1)
方法。
执行代码后,如果两个对象的长度值相同,则 len1==len2 将返回 True。 否则,它将返回 False。
您可以在以下示例中观察到这一点。
class Length:
def __init__(self, value):
self.length = value
def __eq__(self, other):
isLength = isinstance(other, self.__class__)
if not isLength:
return False
if self.length == other.length:
return True
else:
return False
len1 = Length(10)
len2 = Length(10)
result = len1 == len2
print("len1 and len2 are equal:", result)
输出:
len1 and len2 are equal: True
使用 id() 方法的 Python 类相等性
您还可以检查具有自定义类对象的两个变量是否引用同一个对象。 为此,您可以使用 id()
函数。
id()
函数将一个对象作为其输入参数,并在任何内存位置返回一个唯一的标识号。 您可以在以下示例中观察到这一点。
class Length:
def __init__(self, value):
self.length = value
def __eq__(self, other):
isLength = isinstance(other, self.__class__)
if not isLength:
return False
if self.length == other.length:
return True
else:
return False
len1 = Length(10)
len2 = Length(10)
result1 = id(len1)
result2 = id(len2)
print("ID of len1 is ", result1)
print("ID of len2 is ", result2)
输出:
ID of len1 is 140057455513712
ID of len2 is 140057454483488
如果两个对象引用相同的内存位置,则 id()
函数将为两个对象提供相同的输出。 通过比较 id()
函数的输出,我们可以检查对象是否引用相同的内存位置。
您可以在以下示例中观察到这一点。
class Length:
def __init__(self, value):
self.length = value
def __eq__(self, other):
isLength = isinstance(other, self.__class__)
if not isLength:
return False
if self.length == other.length:
return True
else:
return False
len1 = Length(10)
len2 = Length(10)
result1 = id(len1)
result2 = id(len2)
result = result1 == result2
print("len1 and len2 are equal:", result)
输出:
len1 and len2 are equal: False
在这里,我们可以观察到我们没有检查对象中属性的值来检查类是否相等。
在这种情况下,我们只检查对象是否引用相同的内存位置。 因此,这种检查 Python 类相等性的方法等同于使用 == 运算符而不在类定义中实现 __eq__()
方法。