python之比较对象是否相同

背景

在python中,可以使用==判断两边的内容是否相同(即判断两边的内存地址是否相同)。

那么在两个对象(class)中如何比较呢?

==is

在正常情况下,可通过==is进行判断内容是否相同,而is是判断两边的id(内存地址)是否相同。

在普通类型变量中,可以直接使用==判断是否相同,比如:

1
2
3
4
5
6
>>> a = 1
>>> b = 1
>>> a == b
True
>>> a is b
True

我们分别看下上述例子中的a、b的id(即内存地址):

1
2
3
4
>>> id(a)
140467631053320
>>> id(b)
140467631053320

a、b完全相同,所有结果为True

那么在对象中的情况呢:

我们新建一个cat类对象,在创建两个对象进行比较:

1
2
3
4
5
6
>>> class cat():
... name = 'cat'
>>> cat_a = cat()
>>> cat_b = cat()
>>> cat_a == cat_b
False

可以发现cat_a,cat_b内容虽然一样,但是结果为False,我们检查下他们的id:

1
2
3
4
>>> id(cat_a)
4540139208
>>> id(cat_b)
4540139424

可以发现id不同,及在新建对象的时候,会自动分配一个新的内存地址,创建新的对象。

对象的相同判断

但我们希望获得的结果必然是cat_a,cat_b是相同的。这时候我们需要做的是,通过重载对象的__eq__函数,来告诉python如何判断对象是否相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> class cat:
... def __init__(self, name):
... self.name = name
... def __eq__(self, other):
... return self.name == other.name
>>> class cat:
... def __init__(self, name):
... self.name = name
... def __eq__(self, other):
... return self.name == other.name
...
>>> cat_c = cat('a')
>>> cat_d = cat('a')
>>> cat_c == cat_d
True
>>> cat_c is cat_d
False

我们在看此时的cat_c,和cat_d的id情况:

1
2
3
4
>>> id(cat_c)
4540139496
>>> id(cat_d)
4540139424

虽然两者的id不同,但是我们通过重载__eq__函数,修改了对象判断是否相同的方法,从而获取了我们想要的答案,但是id(内存地址)不会变,所以is判断还是为False。

结论

在基本类型的判断中,==is差别不大,但是在对象类型中差异就显现出来了,==判断可以通过重载__eq__函数来修改,而is不行。

通过重载函数,可以按实际情况实现更多情况的比较判断。