web-dev-qa-db-ja.com

Python set([])は2つのオブジェクトが等しいかどうかをどのようにチェックしますか?これをカスタマイズするためにオブジェクトはどのメソッドを定義する必要がありますか?

Pythonで「コンテナ」オブジェクトまたはクラスを作成する必要があります。これは、定義した他のオブジェクトの記録を保持します。このコンテナの1つの要件は、2つのオブジェクトが同一であると見なされる場合、1つ(どちらか)が削除されることです。私の最初の考えは、set([])を包含オブジェクトとして使用して、この要件を完了することでした。

ただし、セットは2つの同一のオブジェクトインスタンスのいずれかを削除しません。作成するには何を定義する必要がありますか?

Pythonコードです。

_class Item(object):
  def __init__(self, foo, bar):
    self.foo = foo
    self.bar = bar
  def __repr__(self):
    return "Item(%s, %s)" % (self.foo, self.bar)
  def __eq__(self, other):
    if isinstance(other, Item):
      return ((self.foo == other.foo) and (self.bar == other.bar))
    else:
      return False
  def __ne__(self, other):
    return (not self.__eq__(other))
_

通訳者

_>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
_

_x == y_によって呼び出される__eq__()は、セットによって呼び出されるメソッドではないことは明らかです。なんていうの?他にどのような方法を定義する必要がありますか?

注:Itemsは変更可能である必要があり、変更できるため、 __hash__()メソッド。これがそれを行う唯一の方法である場合、不変のItemsを使用するために書き直します。

72
Ada

__hash__()メソッドを提供する必要があると思います。ただし、Itemの可変属性に依存しないようにコーディングできます。

29
eumiro

はい、__hash__()- methodと、既に指定した比較演算子が必要です。

class Item(object):
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar
    def __repr__(self):
        return "Item(%s, %s)" % (self.foo, self.bar)
    def __eq__(self, other):
        if isinstance(other, Item):
            return ((self.foo == other.foo) and (self.bar == other.bar))
        else:
            return False
    def __ne__(self, other):
        return (not self.__eq__(other))
    def __hash__(self):
        return hash(self.__repr__())
67
ruena