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
可以比单独比较每个列表元素快得多。