10 Stimmen

Ist der Beizprozess deterministisch?

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.

11voto

Miles Punkte 29684

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

0voto

David Cournapeau Punkte 74679

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).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X