2009-06-12 19 views
7

Czy Pickle zawsze wytwarza takie samo wyjście dla określonej wartości wejściowej? Przypuszczam, że podczas zaznaczania słowników, które mają tę samą zawartość, ale różne historie wstawiania/usuwania, może istnieć błąd. Moim celem jest stworzenie "sygnatury" argumentów funkcji, wykorzystujących Pickle i SHA1, do implementacji memoize.Czy proces wytrawiania jest deterministyczny?

Odpowiedz

7

Podejrzewam, że podczas zaznaczania słowników, które mają tę samą zawartość, ale różne historie wstawiania/usuwania, może istnieć błąd.

prawej:

>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0}) 
False 

Zobacz także: pickle.dumps not suitable for hashing

Moim celem jest stworzenie "sygnaturę" argumentów funkcji, używając marynacie i SHA1, dla realizacji memoize.

Istnieje wiele podstawowych problemów z tym związanych. Nie da się wymyślić transformacji obiektu na ciąg znaków, który mapuje równość poprawnie myśleć o problemie tożsamości obiektu:

>>> a = object() 
>>> b = object() 
>>> a == b 
False 
>>> pickle.dumps(b) == pickle.dumps(a) 
True 

zależności od swoich konkretnych wymagań, może być w stanie przekształcić hierarchie obiektów do tych, które możesz wtedy mieszać:

def hashablize(obj): 
    """Convert a container hierarchy into one that can be hashed. 

    Don't use this with recursive structures! 
    Also, this won't be useful if you pass dictionaries with 
    keys that don't have a total order. 
    Actually, maybe you're best off not using this function at all.""" 
    try: 
     hash(obj) 
    except TypeError: 
     if isinstance(obj, dict): 
      return tuple((k, hashablize(v)) for (k, v) in sorted(obj.iteritems())) 
     elif hasattr(obj, '__iter__'): 
      return tuple(hashablize(o) for o in obj) 
     else: 
      raise TypeError("Can't hashablize object of type %r" % type(obj)) 
    else: 
     return obj 
0

Co masz na myśli przez tę samą wydajność? Powinieneś normalnie zawsze uzyskać ten sam wynik na obie strony (wytrawianie -> rozpakowywanie), ale nie sądzę, aby sam szeregowy format był taki sam w każdym stanie. Z pewnością może się zmieniać między platformami i tak dalej.

Podczas jednego uruchomienia programu, używanie wytrawiania w celu zapamiętywania powinno być w porządku - użyłem tego schematu kilka razy bez problemów, ale to było dla dość prostych problemów. Jeden problem polega na tym, że nie obejmuje to wszystkich użytecznych przypadków (funkcja przychodzi na myśl: nie możesz ich użyć, więc jeśli twoja funkcja przyjmuje argument, który może wywoływać, to nie zadziała).

Powiązane problemy