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

Python list.remove与任意类的奇怪行为-比较对象,python,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 =

我注意到,
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)
我希望它在eq
中输出
,但它不输出任何东西,这意味着
A.。\uuuuueq\uuuu
没有被调用

也不是这个

a1 = A(1, 2)
a2 = A(2, 3)
li = [a1, a2]
li.remove(a1)
li.remove(a2)
触发对
a.\uuuu eq\uuu
的调用

用同一个对象调用
remove
两次,最终调用
A.。\uuuu eq\uuu
,但(奇怪的是)只调用了一次:

a1 = A(1, 2)
a2 = A(1, 2)
li = [a1, a2]
li.remove(a1)
li.remove(a1)
# 'in eq'
  • 为什么一次调用
    remove
    不会调用
    A.\uuuu eq\uuuu
    remove
    如何知道它找到了要删除的对象?Python实现使用内存地址进行比较似乎很奇怪,即使我们重写
    \uuuuueq\uuuu

  • 为什么用同一个对象调用
    A.\uuu eq\uuu
    两次删除
    ,为什么只调用一次


  • 删除方法在使用
    ==
    之前先使用
    ,即
    \uuuuuuuueq\uuuuu
    。因此,如果它发现要使用
    删除的对象是
    ,则不会调用
    \uuuuu eq\uuuu
    。只有当它无法找到
    的对象时,它才会调用
    \uuuuuuueq\uuuuuuu
    。因此,当第二次尝试移除对象时,它会移除相等的对象。在这种情况下,
    a2
    。现在
    li
    为空:

    >>> li.remove(a1)
    >>> li.remove(a1)
    >>> li
    []
    

    当您第三次调用
    li.remove(a1)
    时,您将如我所怀疑的那样设置一个
    ValueError

    。我想知道
    remove
    首先使用
    is
    是否有一个很好的历史原因,即使我们覆盖
    \uuuuuuuueq\uuuu
    。我相信获得的性能是可以忽略的。如果您有一个大的列表要比较,
    is
    可以比单独比较每个列表元素快得多。