views:

42

answers:

1

Say I have a namedtuple like this:

fooTuple = namedtuple("fooTuple", "item1, item2")

And I want the following function to be used for hashing:

fooHash(self):
    return hash(self.item1) * (self.item2)

I want this because I want the order of item1 and item2 to be irrelevant (I will do the same for the comparison-operator). I thought of two ways to do this. The first would be:

fooTuple.__hash__ = fooHash

This works, but it feels hacked. So I tried subclassing fooTuple:

class enhancedFooTuple(fooTuple):
    def __init__(self, item1, item2):
        fooTuple.__init__(self, item1, item2)

    # custom hash function here

But then I get this:

DeprecationWarning: object.__init__() takes no parameters

So, what can I do? Or is this a bad idea altogether and I should just write my own class from scratch?

+3  A: 

I think there is something wrong with your code (my guess is that you created an instance of the tuple with the same name, so fooTuple is now a tuple, not a tuple class), because subclassing the named tuple like that should work. Anyway, you don't need to redefine the constructor. You can just add the hash function:

In [1]: from collections import namedtuple

In [2]: Foo = namedtuple('Foo', ['item1', 'item2'], verbose=False)

In [3]: class ExtendedFoo(Foo):
   ...:     def __hash__(self):
   ...:         return hash(self.item1) * hash(self.item2)
   ...: 

In [4]: foo = ExtendedFoo(1, 2)

In [5]: hash(foo)
Out[5]: 2
Lukáš Lalinský
Thanks, just leaving out the constructor in the subclass fixed the problem.
Space_C0wb0y