2011-12-21 17 views
6
class A(object): 

    def __init__(self, value): 
     self.value = value 

x = A(1) 
y = A(2) 

q = [x, y] 
q.remove(y) 

Listeden önce eklenmiş ve hala referans almış olduğum belirli bir nesneyi kaldırmak istiyorum. Eşitlik testi istemiyorum. Kimlik testi istiyorum. Bu kod hem CPython hem de IronPython'da çalışıyor gibi görünüyor, ancak dil bu davranışı garanti ediyor mu yoksa sadece bir fluke mı?Karşılaştırma işleçlerini geçersiz kılan bir Python nesnesi kendisine eşit mi?

list.remove yöntem belgelerine şudur: same as del s[s.index(x)], bir eşitlik sınamasının gerçekleştirildiğini ima eder. __cmp__, __eq__ veya __ne__'u geçersiz kılmayan bir nesne kendi başına eşit olacak mı?

cevap

9

Evet bakınız. sizin örnekte q.remove(y)y eşit karşılaştırır bir nesnenin ilk geçtiği ortadan kaldıracaktır. Ancak, sınıf A tanım kapsamını, değil † gerektiği hiç bir var Iable y ile eşittir - aynı y örneğine de bağlı olan diğer adlar hariç.

dokümanlar ilgili bölümü here: hiç __cmp__(), __eq__() or __ne__() işlem tanımlanır

ise, sınıf örnekleri nesne kimliğinin ("adres") ile karşılaştırılır.

A örnekleri için karşılaştırma, kimliğe göre (CPython'da bellek adresi olarak uygulanmıştır). Başka hiçbir nesne sürece y bir başvuru tutarken yani için y 'ın ömrü içinde id(y) eşit bir kimliğe sahip olabilir (yapmanız gerekir ki bir listeden çıkarmak için! Gidiyoruz)

Teknik olarak, eşit olarak karşılaştırılan diğer bellek konumlarında nesnelerin bulunması da mümkündür - mock.ANY böyle bir örnektir. Ancak bu nesnelerin, sonuçları zorlamak için karşılaştırma operatörlerini geçersiz kılması gerekir.

+1

Python 3 –

+1

'__cmp__'de [Python 3'de gitti] (https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons) 'ın tersine davranışı tersine görünüyor. Yine de, '__eq__' kullanarak aynı efekti elde edebilirsiniz. – wim

+0

Tanımlanmış bir __eq__ olup olmadığını merak ediyordum, Python 3 adresiyle karşılaştırıyor mu? –

2

Python'da, varsayılan olarak bir nesne her zaman kendisine eşittir (düşünebildiğim tek istisna float("nan"). Kullanıcı tanımlı bir sınıfın nesnesi, bir karşılaştırma işlevi tanımlamadıkça başka bir nesneye eşit olmaz.

da http://docs.python.org/reference/expressions.html#notin

0

Yanıt evet ve hayır.

onlar aynı nesne IFF Bu listeden kaldırır Aşağıdaki örnek

>>> class A(object): 
    def __init__(self, value): 
     self.value = value   
>>> x = A(1) 
>>> y = A(2) 
>>> z = A(3) 
>>> w = A(3) 
>>> q = [x, y,z] 
>>> id(y) #Second element in the list and y has the same reference 
46167248 
>>> id(q[1]) #Second element in the list and y has the same reference 
46167248 
>>> q.remove(y) #So it just compares the id and removes it 
>>> q 
[<__main__.A object at 0x02C19AB0>, <__main__.A object at 0x02C19B50>] 
>>> q.remove(w) #Fails because though z and w contain the same value yet they are different object 
Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    q.remove(w) 
ValueError: list.remove(x): x not in list 

düşünün. Aynı değere sahip farklı bir nesne ise, o kazandı.

+0

Cevap sadece evet, "evet ve hayır" değil. Ve OP açıkça bir kimlik testi, eşitlik testi istemediklerini söyledi. – wim