2012-07-30 84 views
2

我有一个类,我希望为这个类编写一个__hash__()方法。我想写的方法将在某些情况下返回对象的默认散列,并在其他属性中散列其中一个属性的散列。所以,作为一个简单的测试案例:Python - 在__hash__方法定义中使用默认的__hash__方法

class Foo: 
    def __init__(self, bar): 
     self.bar = bar 
    def __hash__(self): 
     if self.bar < 10: 
      return hash(self) # <- this line doesn't work 
     else: 
      return hash(self.bar) 

的问题,这是hash(self)只需调用self.__hash__(),导致无限递归。

据我了解,一个对象的哈希是基于对象的id(),所以我可以重写return hash(self)return id(self),或return id(self)/16,但似乎不好的形式给我重新在我自己的代码的默认实现。

我还想到我可以将它改写为return object.__hash__(self)。这是有效的,但似乎更糟,因为特殊的方法不打算直接调用。

所以,我问的是,有没有一种方法可以使用对象的默认散列而不隐式地调用对象是实例的类的方法__hash__()

+3

在这种情况下直接调用特殊方法是可以的。特别是,当重写一个特殊的方法时,通常可以直接调用同一个方法的超类实现。 – BrenBarn 2012-07-30 06:25:12

回答

6

要调用父类的实现使用:

super(Foo, self).__hash__() 

它也发生在我身上,我可以把它改写为return object.__hash__(self)。这是有效的,但似乎更糟,因为特殊的方法并不打算直接调用。

您正在重写一个神奇的方法,因此可以直接调用父实现。

+0

这是比'object .__ hash __(self)'方法更好的形式吗? – 2012-07-30 06:24:02

+2

在这种情况下,它是相同的。顺便说一句,你用的是Python 3吗?如果不是,你应该有'object'的'Foo'子类。 – warvariuc 2012-07-30 06:26:03