我需要实现__hash__吗?

时间:2014-08-13 15:14:00

标签: python hash set hashtable hashcode

我有这个课程并以__main__

中显示的方式使用它
class User:

  def __init__(self, username, password, isActive):
    self.username = username
    self.password = password
    self.isActive = isActive

  def __str__(self):
    return str(self.__dict__)

  def __eq__(self, other):
      return (isinstance(other, self.__class__)
          and self.__dict__ == other.__dict__)

  def __ne__(self, other):
      return not self.__eq__(other)

  def __hash__(self):
    # Error here: TypeError: tuple() takes at most 1 argument (3 given)
    return hash(tuple(self.username, self.password, self.isActive))

if __name__ == "__main__":
  s1 = set()
  s2 = set()

  # These two instances should be equivalent
  s1.add(User("bob", "12hhjka9#", True))
  s2.add(User("bob", "12hhjka9#", True))

  # These two instances should not be equivalent
  s1.add(User("alice", "12hhjka9#", False))
  s1.add(User("alice", "12hhjka9#", True))

  for user in s1.symmetric_difference(s2):
    print str(user)
  print "done"

此类的实例在构造后永远不会更改,因此在哈希实现中使用实例变量是安全的。我在执行期间遇到此错误:

# Error here: TypeError: tuple() takes at most 1 argument (3 given)

我已尝试__hash__的其他变体,但无法正确使用。救命啊!

2 个答案:

答案 0 :(得分:2)

您只是错误地使用tuple()功能;它甚至不需要。

以下内容可行:

def __hash__(self):
    return hash((self.username, self.password, self.isActive))

tuple()函数只能使用一个参数,但是您传入了3.您将传入另一个可迭代:

return hash(tuple([self.username, self.password, self.isActive]))

但仅使用括号((...))对值进行分组也会产生单个元组。

答案 1 :(得分:0)

您应该考虑使用namedtuple而不是您自己的自定义类。它内置于Python的标准库中。

from collections import namedtuple
User = namedtuple('User', ('username', 'password', 'isActive'))

命名元组是元组的子类,因此已经处理了哈希和等式。