2010-07-11 21 views
13

decir que tengo un namedtuple así:Creación de una namedtuple con una función hash a medida

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

y quiero que la siguiente función que se utilizará para hash:

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

Quiero esto porque quiere que el orden de item1 y item2 sea irrelevante (haré lo mismo para el operador de comparación). Pensé en dos maneras de hacer esto. El primero sería:

FooTuple.__hash__ = foo_hash 

Esto funciona, pero parece pirateado. Así que traté de subclases FooTuple:

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

    # custom hash function here 

Pero entonces me sale esto:

DeprecationWarning: object.__init__() takes no parameters 

Entonces, ¿qué puedo hacer? ¿O es una mala idea y debería escribir mi propia clase desde cero?

Respuesta

18

Creo que hay algo mal con su código (supongo que creó una instancia de la tupla con el mismo nombre, entonces fooTuple ahora es una tupla, no una clase de tupla), porque subclasificando la tupla nombrada de esa manera Deberia trabajar. De todos modos, no es necesario redefinir el constructor. Usted puede simplemente agregar la función hash:

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

Gracias, solo dejando fuera el constructor en la subclase se arregló el problema. –

+11

Tenga en cuenta que 'repr (foo)' seguirá hablando de 'Foo'. Esto podría hacerse mejor como 'clase Foo (namedtuple ('Foo', ['item1', 'item2'], verbose = False)):' –

+0

preste atención a la respuesta de @ Sven [aquí] (http: // stackoverflow. com/questions/4901815/object-of-custom-type-as-dictionary-key) –

Cuestiones relacionadas