Как Python set ([]) проверяет, равны ли два объекта?Какие методы нужно определить объекту, чтобы настроить это? - PullRequest
71 голосов
/ 15 октября 2010

Мне нужно создать контейнерный объект или класс в Python, который хранит записи о других объектах, которые я также определяю.Одним из требований этого контейнера является то, что если два объекта считаются идентичными, один (любой) удаляется.Моей первой мыслью было использовать set([]) в качестве содержащего объекта, чтобы выполнить это требование.

Однако набор не удаляет один из двух идентичных экземпляров объекта.Что я должен определить, чтобы создать один?

Вот код 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)])

Понятно, что __eq__(), который вызывается x == y, это не метод, вызываемый множеством.Что вызвано?Какой другой метод я должен определить?

Примечание: Item s должен оставаться изменяемым и может изменяться, поэтому я не могу предоставить __hash__() метод.Если это единственный способ сделать это, то я перепишу для использования неизменных Item с.

Ответы [ 2 ]

66 голосов
/ 25 июня 2013

Да, вам нужен __hash__() -метод И оператор сравнения, который вы уже предоставили.

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__())
27 голосов
/ 15 октября 2010

Боюсь, вам придется предоставить метод __hash__().Но вы можете закодировать его так, чтобы он не зависел от изменяемых атрибутов вашего Item.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...