Python set([])如何检查两个对象是否相等?对象需要定义哪些方法来自定义它?

Ada*_*Ada 74 python methods comparison set

我需要在Python中创建一个'容器'对象或类,它保存我也定义的其他对象的记录.该容器的一个要求是,如果认为两个对象相同,则移除一个(任一个).我的第一个想法是使用a 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))
Run Code Online (Sandbox Code Playgroud)

翻译员

>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
Run Code Online (Sandbox Code Playgroud)

很明显__eq__(),被调用的x == y不是集合调用的方法.什么叫?我还必须定义什么其他方法?

注意:Items必须保持可变,并且可以更改,因此我无法提供__hash__()方法.如果这是唯一的方法,那么我将重写使用不可变的Items.

小智 67

是的,您需要一个__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__())
Run Code Online (Sandbox Code Playgroud)

  • 在Python 3上,你不需要`__ne__`,即使在2.x中,你也不应该用`__eq__`来定义`__ne__`.请参阅/sf/answers/2147338721/ (3认同)

eum*_*iro 29

恐怕你必须提供一种__hash__()方法.但是你可以按照它的方式对它进行编码,它不依赖于你的可变属性Item.

  • <http://docs.python.org/reference/datamodel.html?highlight=__eq__#object.__hash__>在此处的第二段中,指出__hash __()仅应为不可变对象定义。 (3认同)
  • @Nathanael - 你想怎么称呼__eq__`?比较那些(1,2)属性?然后你必须在你的`__hash__`方法中返回(1,2)的一些哈希值. (2认同)
  • Nathanael:只需使用内置的“hash”:“hash((self.foo, self.bar))”。这使用了元组的哈希,这适合您的需求。(你的 `__eq__` 也可以用 `tuple` 比较来写。) (2认同)