Python LanguageСериализация данных сортировки

Синтаксис

  • pickle.dump (объект, файл, протокол) # Для сериализации объекта

  • pickle.load (file) # Чтобы де-сериализовать объект

  • pickle.dumps (объект, протокол) # Сериализация объекта в байтах

  • pickle.loads (buffer) # Для де-сериализации объекта из байтов

параметры

параметр подробности
объект Объект, который должен быть сохранен
файл Открытый файл, который будет содержать объект
протокол Протокол, используемый для травления объекта (необязательный параметр)
буфер Объект bytes, который содержит сериализованный объект

замечания

Распылительные типы

Следующие объекты являются picklable.

  • None , True и False
  • числа (всех типов)
  • строки (всех типов)
  • tuple s, list s, set s и dict s, содержащий только сортируемые объекты
  • функции, определенные на верхнем уровне модуля
  • встроенные функции
  • классы, которые определены на верхнем уровне модуля

На основе официальной документации Python .

pickle и безопасность

Модуль рассола не является безопасным . Он не должен использоваться при получении сериализованных данных от ненадежной стороны, например, через Интернет.

Использование Pickle для сериализации и десериализации объекта

Модуль pickle реализует алгоритм превращения произвольного объекта Python в ряд байтов. Этот процесс также называется сериализацией объекта. Затем поток байтов, представляющий объект, может быть передан или сохранен, а затем реконструирован для создания нового объекта с теми же характеристиками.

Для простейшего кода мы используем функции dump() и load() .

Сериализация объекта

import pickle

# An arbitrary collection of objects supported by pickle.
data = {
    'a': [1, 2.0, 3, 4+6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('data.pickle', 'wb') as f:
    # Pickle the 'data' dictionary using the highest protocol available.
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)

Для десериализации объекта

import pickle

with open('data.pickle', 'rb') as f:
    # The protocol version used is detected automatically, so we do not
    # have to specify it.
    data = pickle.load(f)

Использование объектов рассола и байтов

Также возможно сериализовать и дезаминировать из байтовых объектов, используя функцию dumps и loads , которые эквивалентны dump и load .

serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
# type(serialized_data) is bytes

deserialized_data = pickle.loads(serialized_data)
# deserialized_data == data

Настроить маринованные данные

Некоторые данные нельзя травить. Другие данные не следует мариновать по другим причинам.

То, что будет маринован, может быть определено в методе __getstate__ . Этот метод должен возвращать то, что может быть сорвано.

На противоположной стороне __setstate__ : он получит то, что создал __getstate__ и должен инициализировать объект.

class A(object):
    def __init__(self, important_data):
        self.important_data = important_data
        
        # Add data which cannot be pickled:
        self.func = lambda: 7
        
        # Add data which should never be pickled, because it expires quickly:
        self.is_up_to_date = False
    
    def __getstate__(self):
        return [self.important_data] # only this is needed
    
    def __setstate__(self, state):
        self.important_data = state[0]
        
        self.func = lambda: 7  # just some hard-coded unpicklable function
        
        self.is_up_to_date = False  # even if it was before pickling

Теперь это можно сделать:

>>> a1 = A('very important')
>>>
>>> s = pickle.dumps(a1)  # calls a1.__getstate__()
>>>
>>> a2 = pickle.loads(s)  # calls a1.__setstate__(['very important'])
>>> a2
<__main__.A object at 0x0000000002742470>
>>> a2.important_data
'very important'
>>> a2.func()
7

Реализация здесь отображает список с одним значением: [self.important_data] . Это был всего лишь пример, __getstate__ мог бы вернуть все, что можно выбрать, если __setstate__ знает, как сделать oppoisite. Хорошей альтернативой является словарь всех значений: {'important_data': self.important_data} .

Конструктор не называется! Обратите внимание, что в предыдущем примере экземпляр a2 был создан в pickle.loads без вызова A.__init__ , поэтому A.__setstate__ должен был инициализировать все, что __init__ инициализировалось бы, если бы оно было A.__setstate__ .