Понимание маринования в Python - PullRequest
54 голосов
/ 21 сентября 2011

Недавно я получил задание, где мне нужно поместить словарь (где каждый ключ относится к списку) в маринованной форме.Единственная проблема в том, что я понятия не имею, что такое маринованная форма.Может ли кто-нибудь указать мне правильное направление, чтобы найти полезные ресурсы, чтобы помочь мне изучить эту концепцию?Спасибо!

Ответы [ 6 ]

86 голосов
/ 21 сентября 2011

Модуль pickle реализует фундаментальный, но мощный алгоритм для сериализации и десериализации структуры объекта Python.

Pickling - - это процесс, посредством которого иерархия объектов Python преобразуется в поток байтов, а Unpickling - - обратная операция, в результате которой поток байтов преобразуется обратно в объект иерархия.

Травление (и удаление) также известно как сериализация , сортировка или уплощение .

import pickle

data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()

Для чтения из маринованного файла -

import pprint, pickle

pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()

источник - https://docs.python.org/2/library/pickle.html

22 голосов
/ 15 ноября 2014

Pickling - это мини-язык, который можно использовать для преобразования соответствующего состояния из объекта python в строку, где эта строка однозначно представляет объект. Затем (un) травление может быть использовано для преобразования строки в живой объект путем «восстановления» объекта из сохраненного состояния и создания строки.

>>> import pickle
>>> 
>>> class Foo(object):
...   y = 1
...   def __init__(self, x):
...     self.x = x
...     return
...   def bar(self, y):
...     return self.x + y
...   def baz(self, y):
...     Foo.y = y  
...     return self.bar(y)
... 
>>> f = Foo(2)
>>> f.baz(3)
5
>>> f.y
3
>>> pickle.dumps(f)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI2\nsb."

Здесь вы можете видеть, что pickle не сохраняет исходный код для класса, но сохраняет ссылку на определение класса. По сути, вы можете почти прочитать выбранную строку… она говорит (грубо переведено) «вызовите реконструктор copy_reg, где аргументы - это класс, определенный __main__.Foo, а затем выполните другие действия». Другой материал - это сохраненное состояние экземпляра. Если вы посмотрите глубже, вы можете извлечь, что «строка x» установлена ​​в «целое число 2» (примерно: S'x'\np6\nI2). На самом деле это вырезанная часть маринованной строки для словарной статьи… dict означает f.__dict__, что составляет {'x': 2}. Если вы посмотрите на исходный код pickle, он очень четко дает перевод для каждого типа объекта и операции с python на маринованный байт-код.

Обратите внимание, что существуют разные варианты языка травления. По умолчанию используется протокол 0, который более понятен человеку. Также есть протокол 2, показанный ниже (и 1,3, и 4, в зависимости от используемой вами версии Python).

>>> pickle.dumps([1,2,3])
'(lp0\nI1\naI2\naI3\na.'
>>> 
>>> pickle.dumps([1,2,3], -1)
'\x80\x02]q\x00(K\x01K\x02K\x03e.'

Опять же, это все еще диалект языка травления, и вы можете видеть, что в строке протокола 0 написано «получить список, включите I1, I2, I3», в то время как протокол 2 труднее читать, но говорит то же вещь. Первый бит \x80\x02 указывает, что это протокол 2 - тогда у вас есть ], который говорит, что это список, и снова вы можете видеть целые числа 1,2,3 там. Опять же, проверьте исходный код для pickle, чтобы увидеть точное отображение для языка pickle.

Чтобы перевернуть травление в строку, используйте load / load.

>>> p = pickle.dumps([1,2,3])
>>> pickle.loads(p)
[1, 2, 3]
11 голосов
/ 21 сентября 2011

Pickling - это просто сериализация: помещение данных в форму, которую можно сохранить в файле и получить позже. Вот документы по модулю pickle:

http://docs.python.org/release/2.7/library/pickle.html

3 голосов
/ 21 сентября 2011

Pickling in Python используется для сериализации и десериализации объектов Python, как словарь в вашем случае. Я обычно использую модуль cPickle, так как он может быть намного быстрее, чем модуль Pickle.

import cPickle as pickle    

def serializeObject(pythonObj):
    return pickle.dumps(pythonObj, pickle.HIGHEST_PROTOCOL)

def deSerializeObject(pickledObj):
    return pickle.loads(pickledObj)
3 голосов
/ 21 сентября 2011

http://docs.python.org/library/pickle.html#example

import pickle

data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()
2 голосов
/ 18 октября 2017

Модуль pickle реализует фундаментальный, но мощный алгоритм для сериализации и десериализации структуры объекта Python. «Pickling» - это процесс, посредством которого иерархия объектов Python преобразуется в поток байтов, а «uncickling» - обратная операция, посредством которой поток байтов преобразуется обратно в иерархию объектов. Травление (и расслоение) также известно как «сериализация», «маршалинг» или «выравнивание», однако во избежание путаницы здесь используются термины «травление» и «расслоение».

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

Потоки данных, создаваемые двумя модулями, гарантированно являются взаимозаменяемыми.

...