Подтвердить что ты не робот

Выбор протокола Python?

Я использую python 2.7 и пытаюсь рассолить объект. Мне интересно, какова реальная разница между протоколами рассола.

import numpy as np
import pickle
class data(object):
    def __init__(self):
        self.a = np.zeros((100, 37000, 3), dtype=np.float32)

d = data()
print "data size: ", d.a.nbytes/1000000.
print "highest protocol: ", pickle.HIGHEST_PROTOCOL
pickle.dump(d,open("noProt", 'w'))
pickle.dump(d,open("prot0", 'w'), protocol=0)
pickle.dump(d,open("prot1", 'w'), protocol=1)
pickle.dump(d,open("prot2", 'w'), protocol=2)


out >> data size:  44.4
out >> highest protocol:  2

то я обнаружил, что сохраненные файлы имеют разные размеры на диске:

  • noProt: 177.6MB
  • prot0: 177.6MB
  • prot1: 44.4MB
  • prot2: 44.4MB

Я знаю, что prot0 является читаемым человеком текстовым файлом, поэтому я не хочу его использовать. Я полагаю, что протокол 0 задан по умолчанию.

Интересно, какая разница между протоколами 1 и 2, есть ли причина, по которой я должен был выбрать тот или иной?

Чем лучше использовать, pickle или cPickle?

4b9b3361

Ответ 1

Из pickle документации по формату данных модуля:

В настоящее время существует 3 разных протокола, которые можно использовать для травления.

  • Версия протокола 0 является исходным протоколом ASCII и обратно совместима с более ранними версиями Python.
  • Протокол версии 1 - это старый двоичный формат, который также совместим с более ранними версиями Python.
  • Протокол версии 2 был представлен на Python 2.3. Он обеспечивает гораздо более эффективное расчесывание классов нового стиля.

[...]

Если протокол не указан, используется протокол 0. Если протокол указан как отрицательное значение или HIGHEST_PROTOCOL, будет использоваться самая высокая версия протокола.

Используйте протокол версии 2, особенно если вы используете пользовательские классы, полученные из object (классы нового стиля). Какой самый современный код делает в наши дни.

Если вам не требуется поддерживать обратную совместимость со старыми версиями Python, проще всего придерживаться самой высокой версии протокола, на которую вы можете положиться:

with open("prot2", 'wb') as pfile:
    pickle.dump(d, pfile, protocol=pickle.HIGHEST_PROTOCOL)

Поскольку это двоичный формат, обязательно используйте 'wb' как режим файла!

cPickle и pickle в основном совместимы; различия заключаются в предлагаемом API. Для большинства случаев использования просто придерживайтесь cPickle; это быстрее. Цитирование документации:

Во-первых, cPickle может быть до 1000 раз быстрее, чем рассол, потому что первая реализована в C. Во-вторых, в модуле cPickle вызывающие символы Pickler() и Unpickler() являются функциями, а не классами. Это означает, что вы не можете использовать их для получения настраиваемых подклассов травления и рассыпания. Большинство приложений не нуждаются в этой функции и должны извлечь выгоду из значительно улучшенной производительности модуля cPickle.

Ответ 2

Для пользователей, использующих Python 3, на Python 3.5 есть пять возможных протоколов на выбор:

В настоящее время существует 5 различных протоколов, которые можно использовать для травления. Чем выше используемый протокол, тем более поздняя версия Python должна была прочитать полученный порошок [doc ]:

  • Протокол версии 0 является исходным "человекочитаемым" протоколом и обратно совместим с более ранними версиями Python.

  • Протокол версии 1 представляет собой старый двоичный формат, который также совместим с более ранними версиями Python.

  • Протокол версии 2 был представлен на Python 2.3. Он обеспечивает гораздо более эффективное расчесывание классов нового стиля. См. PEP 307 для информация об улучшениях, внесенных протоколом 2.
  • Версия протокола 3 была добавлена ​​в Python 3.0. Он имеет явную поддержку для объектов байтов и не может быть распечатан Python 2.x. Эта это протокол по умолчанию и рекомендуемый протокол, когда требуется совместимость с другими версиями Python 3.
  • Протокол версии 4 был добавлен в Python 3.4. Он добавляет поддержку очень больших объектов, травит больше видов объектов, а некоторые данные оптимизация формата. Обратитесь к PEP 3154 за информацией о улучшения, внесенные протоколом 4.

Общее правило заключается в том, что вы должны использовать максимально возможный протокол, который обратно совместим с тем, для чего вы хотите его использовать. Поэтому, если вы хотите, чтобы он был обратно совместим с Python 2, то протокол версии 2 является хорошим выбором, если вы хотите, чтобы он был обратно совместим со всеми версиями Python, тогда версия 1 хороша. Если вам не нужна обратная совместимость, то с помощью pickle.HIGHEST_PROTOCOL автоматически вы получите самый высокий протокол для вашей версии Python.

Также в Python 3 импорт pickle автоматически импортирует реализацию C.

Еще одно замечание в отношении совместимости состоит в том, что по умолчанию протоколы 3 и 4 используют кодировку Unicode строк, тогда как в предыдущих протоколах нет. Поэтому в Python 3, если вы загружаете маринованный файл, который был маринован в Python 2, вам, вероятно, придется явно указать кодировку, чтобы правильно загрузить ее.