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

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

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

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

以前に追加された特定のオブジェクトをリストから削除したいのですが、まだ参照があります。私は平等テストを望んでいません。私はアイデンティティテストをしたい。このコードはCPythonとIronPythonの両方で動作するようですが、言語でこの動作が保証されているのですか?比較演算子をオーバーライドしないPythonオブジェクトは、それ自身と同じですか?

list.removeメソッドドキュメントは、same as del s[s.index(x)]です。これは、同等性テストが実行されることを意味します。

__cmp____eq__、または__ne__を上書きしないと、オブジェクト自体と同じになりますか?

答えて

9

はいを参照してください。あなたの例ではq.remove(y)yと同等の比較対象の最初の発生を削除します。ただし、クラスAが定義されている方法は、あなたがいない†べきこれまでvarを持っています同じyインスタンスにもバインドされている他の名前を除いて、i37はyと等しくなります。

ドキュメントの関連セクションはhereある:

__cmp__(), __eq__() or __ne__()操作が定義されていない場合、クラス インスタンスがオブジェクトID(「アドレス」)によって比較されます。

したがって、Aインスタンスの比較はID(CPythonのメモリアドレスとして実装されています)です。他のオブジェクトには、限り、あなたはy(あなたがしなければならない、あなたはリストから削除するつもりなら!)

への参照を保持するようすなわち ため、yの寿命内id(y)に等しいアイデンティティを持つことはできません

技術的には、技術的には、同等のものを比較している他のメモリ位置にオブジェクトを持つことは技術的には可能です。mock.ANYがこのような例の1つです。しかし、これらのオブジェクトは結果を強制するために比較演算子をオーバーライドする必要があります。

+1

興味深いことに、振る舞いはPython 3の逆であるようです。 –

+1

'__cmp__'は[Python 3でなくなった]です(https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons)。あなたは '__eq__'を使って同じ効果を達成することができます。 – wim

+0

__eq__が定義されていないのでしょうか?Python 3はアドレスで比較しますか? –

2

デフォルトでは、オブジェクトは常に自分と等しいです(唯一の例外はfloat("nan")です)。比較関数を定義しない限り、ユーザー定義クラスのオブジェクトは他のオブジェクトと等しくありません。

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

0

答えははい、いいえです。

は、彼らが同じオブジェクトである場合に限っそれはリストから削除されます、次の例

>>> 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 

を考えてみましょう。それらが同じ値を持つ異なるオブジェクトであれば、それを取り除きます。

+0

答えは単にはいです。「はい、いいえ」ではありません。 OPは明示的には同一性テストではなく、同一性テストをしたいと明言した。 – wim

関連する問題