Понимание травления в Python

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


person Spencer    schedule 21.09.2011    source источник
comment
docs.python.org/library/pickle.html — это первый результат поиска в Google по запросу pickle. , даже превзойдя страницу Википедии для консервированного овоща.   -  person Wooble    schedule 21.09.2011
comment
@Wooble: Я знаю, что это совершенно не по теме, но поиск в Google зависит от вашего местоположения, истории поиска и даже истории электронной почты/чата ;). Но да, +1 за указание на документы.   -  person 0xc0de    schedule 26.09.2014
comment
@ 0xc0de Верно. Для меня главная запись это консервированные овощи. :-) Думаю, мне следует начать кодировать больше.   -  person Sibbs Gambling    schedule 21.02.2017
comment
См. также: Как использовать pickle для хранения/загрузки данных   -  person Martin Thoma    schedule 04.01.2018


Ответы (6)


Модуль 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

person Srikar Appalaraju    schedule 21.09.2011
comment
Это просто один из лучших примеров кода, которые я когда-либо видел. Красиво оформленный и удивительно лаконичный. Спасибо. - person anon58192932; 26.06.2014
comment
Я не понял, почему data1 = pickle.load(pkl_file) не загрузил полный файл (data.pkl)? - person Naive; 21.10.2015
comment
Требуется ли для травления выходной параметр файла? Как сохранить сериализованный объект в другом месте? - person Praxiteles; 29.05.2017
comment
Для тех, кто использует Python 3: pickle.dump(data1, output) по умолчанию имеет значение pickle.DEFAULT_PROTOCOL (протокол 3 на момент написания этого комментария), а не протокол 0. - person Matt Eding; 27.01.2018

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

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

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

>>> p = pickle.dumps([1,2,3])
>>> pickle.loads(p)
[1, 2, 3]
person Mike McKerns    schedule 15.11.2014
comment
Как новичок, у меня в голове был этот вопрос, что за маринад делает внутри? Этот ответ касался этого больше, чем другие. - person Whirl Mind; 13.01.2016

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

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

person Tom Zych    schedule 21.09.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()
person John Riselvato    schedule 21.09.2011

Pickling в 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)
person Raunak    schedule 21.09.2011
comment
Какая польза от Highest.protocol? - person BoRRis; 12.11.2018

Pickling позволяет сериализовать и десериализовать структуры объектов Python. Короче говоря, Pickling — это способ преобразовать объект Python в поток символов, чтобы этот поток символов содержал всю информацию, необходимую для восстановления объекта в другом скрипте Python.

import pickle

def pickle_data():
    data = {
           'name': 'sanjay',
           'profession': 'Software Engineer',
           'country': 'India'
        }
    filename = 'PersonalInfo'
    outfile = open(filename, 'wb')
    pickle.dump(data,outfile)
    outfile.close()

pickle_data()
person sanjay    schedule 15.10.2020