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

Python: зачем мариновать?

Я использую рассол и был очень доволен, тогда я увидел эту статью: Не рассортировать ваши данные

Чтение далее выглядит следующим образом:

Ive переключился на сохранение моих данных как JSON, но я хотел узнать о лучшей практике:

Учитывая все эти проблемы, когда вы когда-нибудь будете использовать рассол? Какие конкретные ситуации требуют его использования?

4b9b3361

Ответ 1

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

  • Быстрая и простая сериализация, например, для приостановки и возобновления длительной, но простой script. Здесь нет никакой проблемы, вы просто хотите сбросить состояние программы как есть и загрузить ее позже.
  • Отправка произвольных данных Python другим процессам или компьютерам, как в multiprocessing. Проблемы безопасности могут применяться (но в большинстве случаев это не так), общность абсолютно необходима, и людям не придется ее читать.

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

Вы заметите, что я полностью проигнорировал "медленный" недостаток. Это потому, что оно частично вводит в заблуждение: Pickle действительно медленнее для данных, которые идеально подходят для модели JSON (строки, числа, массивы, карты), но если ваши данные подобны, вы должны использовать JSON по другим причинам. Если ваши данные не так (скорее всего), вам также необходимо принять во внимание настраиваемый код, который вам нужно будет превратить ваши объекты в данные JSON, и настраиваемый код, который вам нужно будет вернуть данные JSON в ваш объекты. Он добавляет как инженерные усилия, так и затраты времени на выполнение, которые должны быть количественно определены в каждом конкретном случае.

Ответ 2

У Pickle есть преимущество в удобстве - он может сериализовать произвольные графические объекты без дополнительной работы и работает на довольно широком диапазоне типов Python. С учетом сказанного мне было бы необычно использовать Pickle в новом коде. JSON работает намного чище для работы.

Ответ 3

Обычно я не использую ни Pickle, ни JSON, но MessagePack он безопасен и быстр и создает сериализованные данные небольшого размера.

Дополнительным преимуществом является возможность обмена данными с программным обеспечением, написанным на других языках (что, конечно же, верно и в случае JSON).

Ответ 4

Вы можете найти ответ на JSON против безопасности Pickle: JSON может выбирать только unicode, int, float, NoneType, bool, list и dict. Вы не можете использовать его, если хотите рассортировать более сложные объекты, такие как экземпляр классов. Обратите внимание, что для этих видов рассола нет никакой надежды быть агностиком языка.

Также использование cPickle вместо Pickle частично разрешает скорость.

Ответ 5

Я пробовал несколько методов и выяснил, что использование cPickle с настройкой аргумента протокола метода дампов как: cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL) является самым быстрым методом дампа.

import msgpack
import json
import pickle
import timeit
import cPickle
import numpy as np

num_tests = 10

obj = np.random.normal(0.5, 1, [240, 320, 3])

command = 'pickle.dumps(obj)'
setup = 'from __main__ import pickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("pickle:  %f seconds" % result)

command = 'cPickle.dumps(obj)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle:   %f seconds" % result)


command = 'cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)'
setup = 'from __main__ import cPickle, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("cPickle highest:   %f seconds" % result)

command = 'json.dumps(obj.tolist())'
setup = 'from __main__ import json, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("json:   %f seconds" % result)


command = 'msgpack.packb(obj.tolist())'
setup = 'from __main__ import msgpack, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("msgpack:   %f seconds" % result)

Вывод:

pickle         :   0.847938 seconds
cPickle        :   0.810384 seconds
cPickle highest:   0.004283 seconds
json           :   1.769215 seconds
msgpack        :   0.270886 seconds

Итак, я предпочитаю cPickle с самым высоким протоколом демпинга в ситуациях, требующих производительности в реальном времени, таких как потоковая передача видео с камеры на сервер.