Является ли процесс травления детерминированным? - PullRequest
8 голосов
/ 12 июня 2009

Всегда ли Pickle выдает один и тот же выход для определенного входного значения? Я полагаю, что при выборе словарей, имеющих одинаковое содержимое, но разную историю вставки / удаления, может возникнуть ошибка. Моя цель - создать «сигнатуру» аргументов функции, используя Pickle и SHA1, для реализации памятки.

Ответы [ 2 ]

8 голосов
/ 12 июня 2009

Я полагаю, что при выборе словарей, имеющих одинаковое содержимое, но разные истории вставки / удаления, может возникнуть ошибка.

Справа:

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

См. Также: pickle.dumps не подходит для хеширования

Моя цель - создать «сигнатуру» аргументов функции, используя Pickle и SHA1, для реализации памятки.

Есть ряд фундаментальных проблем с этим. Невозможно придумать преобразование объекта в строку, которое правильно отображает равенство - подумайте о проблеме идентичности объекта:

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

В зависимости от ваших точных требований, вы можете преобразовать иерархии объектов в те, которые вы можете затем хешировать:

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 голосов
/ 12 июня 2009

Что вы подразумеваете под тем же выводом? Обычно вы должны всегда получать один и тот же вывод для циклической обработки (засечка -> разборка), но я не думаю, что сам сериализованный формат гарантированно будет одинаковым в любых условиях. Конечно, это может измениться между платформами и всем этим.

В пределах одного прогона вашей программы использование маринования для запоминания должно быть хорошо - я использовал эту схему несколько раз без проблем, но это было для довольно простых проблем. Одна проблема заключается в том, что это не охватывает все полезные случаи (на ум приходит функция: вы не можете их выбрать, поэтому, если ваша функция принимает вызываемый аргумент, это не будет работать).

...