Выбор протокола 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
?
Ответы
Ответ 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, вам, вероятно, придется явно указать кодировку, чтобы правильно загрузить ее.