2014-10-22 12 views
17

Ben var bana başımı çizik yapıyor Aşağıdaki kod, -__eq__ çağrılmıyorken nesneyim neden bir listeden düzgün şekilde kaldırılıyor?

before [a, b, c, d] 
comparing a to d (False) 
comparing b to d (False) 
comparing c to d (False) 
after [a, b, c] 

Neden comparing d to d (True) çıkışı değil eq() edilir - şu çıktıyı verir

class Element: 
    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return self.name 

def eq(self, other): 
    print('comparing {} to {} ({})'.format(self.name, 
     other.name, 
     self.name == other.name)) 

    return self.name == other.name 

Element.__eq__ = eq 
elements = [ 
    Element('a'), 
    Element('b'), 
    Element('c'), 
    Element('d')  
] 

print('before {}'.format(elements)) 
elements.remove(elements[3]) 
print('after {}'.format(elements)) 

?

Element sınıfında basitçe uygulamak yerine __eq__ numaralı düzeltme ekini kullanmamın nedeni, kullanıyorum kitaplıklarımdan birini uygulayabilmem için nasıl bir düzeltme ekinin çalıştığını test etmem.

cevap

16

Dördüncü öğe, kodun iletildiği nesne ile aynı nesnedir (elements[3]). Başka bir deyimle

,
>>> elements[3] is elements[3] 
True 
>>> elements[3] == elements[3] 
True 

Yani, onlar (?) özdeş (aynı) biriz çünkü eşitliğini kontrol etmeye gerek.

Eşit olmadıklarında eşitlik kontrolü yapılacaktır. Her iki nesnenin özdeş

elements.remove(Element('d')) 
+0

Teşekkür ederiz. Çok açık bir cevap. –

9

Python'ın list.remove() bir yöntem, ilk olup olmadığını kontrol eder, aksi takdirde, bu durumda __eq__ gibi normal karşılaştırma yöntemleri geri döner: Kod aynı değere sahip diğer bir amacı geçer Örneğin, __eq__ çağrılır. Yani, bu durumda her iki nesne aynı olduğu için listeden kaldırılır. İşte PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid)

listremove(PyListObject *self, PyObject *v) 
{ 
    Py_ssize_t i; 

    for (i = 0; i < Py_SIZE(self); i++) { 
     int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ); 
     ... 

karşılaştırma için kullanılır ve bunun dokümanlardan ediliyor: aynı nesne

o1 ise ve o2, PyObject_RichCompareBool() daima Py_NE için Py_EQ için 1 ve 0 dönecektir.

+0

Python'un gerçek uygulama kaynak kodunun bir pasajını gönderdiğiniz için teşekkür ederiz. Cevaplarıma bakmak için gerçekten öğrenmeliyim. –

İlgili konular