2010-07-11 14 views
13

que j'ai un namedtuple comme ceci:Création d'un namedtuple avec une fonction de hachage personnalisé

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

Et je veux que la fonction suivante à utiliser pour le hachage:

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

Je veux parce que je Je veux que l'ordre de item1 et item2 soit sans importance (je ferai de même pour l'opérateur de comparaison). J'ai pensé à deux façons de le faire. Le premier serait:

FooTuple.__hash__ = foo_hash 

Cela fonctionne, mais il se sent piraté. J'ai donc essayé subclassing FooTuple:

class EnhancedFooTuple(FooTuple): 
    def __init__(self, item1, item2): 
     FooTuple.__init__(self, item1, item2) 

    # custom hash function here 

Mais je reçois ceci:

DeprecationWarning: object.__init__() takes no parameters 

Alors, que puis-je faire? Ou est-ce une mauvaise idée et je devrais écrire ma propre classe à partir de zéro?

Répondre

18

Je pense qu'il y a un problème avec votre code (je suppose que vous avez créé une instance du tuple du même nom, donc fooTuple est maintenant un tuple, pas une classe tuple), parce que le tuple nommé est comme ça devrait marcher. De toute façon, vous n'avez pas besoin de redéfinir le constructeur. Vous pouvez simplement ajouter la fonction de hachage:

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 
+0

Merci, en omettant le constructeur dans la sous-classe a résolu le problème. –

+11

Notez que 'repr (foo)' parlera toujours de 'Foo'. Cela pourrait être mieux fait en tant que classe Foo (namedtuple ('Foo', ['item1', 'item2'], verbose = False)): ' –

+0

faites attention à la réponse @ Sven [ici] (http: // stackoverflow. com/questions/4901815/objet-de-custom-type-comme-dictionnaire-clé) –