list.remove与任意类的奇怪行为 - 比较对象

时间:2017-02-16 13:21:41

标签: python

我注意到list.remove的一些奇怪的行为,通过越过C源无法解释(至少是我)。

考虑这个课程:

class A:
    def __init__(self, n1, n2):
        self.n1 = n1
        self.n2 = n2

    def __eq__(self, other):
        print('in eq')
        return vars(self) == vars(other)

以下代码:

a1 = A(1, 2)
a2 = A(1, 2)
li = [a1, a2]
li.remove(a1)

我希望它输出in eq,但它不输出任何意味着A.__eq__没有被调用。

这两个

a1 = A(1, 2)
a2 = A(2, 3)
li = [a1, a2]
li.remove(a1)
li.remove(a2)

触发对A.__eq__的调用。

使用同一个对象调用remove两次最终调用A.__eq__,但(奇怪的是)只调用一次:

a1 = A(1, 2)
a2 = A(1, 2)
li = [a1, a2]
li.remove(a1)
li.remove(a1)
# 'in eq'
  1. 为什么拨打remove一次不会拨打A.__eq__remove如何知道它找到了要删除的对象?使用内存地址进行比较似乎很奇怪,即使我们覆盖__eq__

  2. 为什么使用相同的对象调用remove两次调用A.__eq__,为什么只调用一次?

1 个答案:

答案 0 :(得分:1)

删除方法在使用is之前首先使用==,即__eq__。因此,如果它找到您要使用is删除的对象,则不会调用__eq__。仅当__eq__无法找到is的对象时,才会调用a2。因此,当第二次尝试删除对象时,它会删除相同的对象。在这种情况下li。现在>>> li.remove(a1) >>> li.remove(a1) >>> li [] 为空:

li.remove(a1)

当您第三次致电ValueError时,您将会describe('Some definition', function () { // ... unit tests }