Erzeugt Pickle für einen bestimmten Eingabewert immer die gleiche Ausgabe? Ich vermute, dass es ein Problem geben könnte, wenn man Wörterbücher mit gleichem Inhalt, aber unterschiedlicher Einfüge-/Löschhistorie einpickt. Mein Ziel ist es, eine "Signatur" von Funktionsargumenten zu erstellen, mit Pickle und SHA1, für eine memoize Implementierung.
Antworten
Zu viele Anzeigen?Ich vermute, dass es ein Problem geben könnte, wenn man Wörterbücher mit gleichem Inhalt, aber unterschiedlicher Einfüge-/Löschhistorie in die Datenbank einfügt.
Richtig:
>>> pickle.dumps({1: 0, 9: 0}) == pickle.dumps({9: 0, 1: 0})
False
Siehe auch: pickle.dumps nicht zum Hashing geeignet
Mein Ziel ist es, eine "Signatur" von Funktionsargumenten unter Verwendung von Pickle und SHA1 für eine memoize-Implementierung zu erstellen.
Hier gibt es eine Reihe von grundlegenden Problemen. Es ist unmöglich, eine Objekt-zu-Zeichenfolge-Transformation zu entwickeln, die Gleichheit korrekt abbildet - man denke nur an das Problem der Objektidentität:
>>> a = object()
>>> b = object()
>>> a == b
False
>>> pickle.dumps(b) == pickle.dumps(a)
True
Je nach Ihren genauen Anforderungen können Sie möglicherweise Objekthierarchien in solche umwandeln, die Sie dann in Hash umwandeln können:
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
Was meinen Sie mit gleicher Leistung? Normalerweise sollten Sie bei einem Roundtrip (Beizen -> Entbeizen) immer die gleiche Ausgabe erhalten, aber ich glaube nicht, dass das serialisierte Format selbst garantiert in jeder Situation gleich ist. Sicherlich kann es sich von Plattform zu Plattform ändern und so weiter.
Innerhalb eines Durchlaufs Ihres Programms sollte die Verwendung von Pickling für die Memoisierung in Ordnung sein - ich habe dieses Schema schon einige Male ohne Probleme verwendet, aber das war für recht einfache Probleme. Ein Problem ist, dass dies nicht jeden nützlichen Fall abdeckt (Funktionen kommen mir in den Sinn: man kann sie nicht beizen, also wenn Ihre Funktion ein aufrufbares Argument nimmt, wird das nicht funktionieren).