我注意到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'
为什么拨打remove
一次不会拨打A.__eq__
? remove
如何知道它找到了要删除的对象?使用内存地址进行比较似乎很奇怪,即使我们覆盖__eq__
。
为什么使用相同的对象调用remove
两次调用A.__eq__
,为什么只调用一次?
答案 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
}