Pickle.load: примеры (PYTHON)

Использование pickle.load для восстановления объектов в Python
Раздел: Сериализация, Бинарная сериализация
pickle.load(file: file object): any

Функция pickle.load для десериализации объектов

Функция pickle.load в Python выполняет десериализацию объектов из бинарного потока данных. Её применяют для восстановления ранее сериализованных объектов, сохраненных с помощью pickle.dump.

Основные случаи использования включают сохранение состояния программы, кэширование вычислений, обмен данными между процессами Python.

Синтаксис: pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)

  • file - объект файла, открытый для чтения в двоичном режиме ('rb'), или объект, поддерживающий метод read() и возвращающий байты.
  • fix_imports - флаг, разрешающий автоматическое преобразование устаревших имён модулей Python 2 в соответствующие имена в Python 3. Значение по умолчанию: True.
  • encoding - кодировка для декодирования строк Python 2; по умолчанию 'ASCII'. Используется только при чтении пиклов, созданных в Python 2.
  • errors - стратегия обработки ошибок декодирования; по умолчанию 'strict'. Применяется только для строк Python 2.
  • buffers - необязательный итерируемый объект, содержащий буферы для протокола 5 и выше. Если передан None, все данные должны быть включены в пикл.

Функция возвращает десериализованный объект Python. Если достигнут конец файла, возникает исключение EOFError.

Базовые примеры использования pickle.load

Десериализация простого объекта из файла:

import pickle

with open('data.pkl', 'rb') as f:
    data = pickle.load(f)
    print(type(data))

Чтение нескольких объектов из одного файла:

import pickle

with open('multi.pkl', 'rb') as f:
    while True:
        try:
            obj = pickle.load(f)
            print(obj)
        except EOFError:
            break
[1, 2, 3]
{'key': 'value'}
42

Использование параметров для данных Python 2:

import pickle

# Для пиклов, созданных в Python 2 с не-ASCII строками
with open('py2_data.pkl', 'rb') as f:
    data = pickle.load(f, encoding='latin1')
    print(data)
'café'

Альтернативные функции сериализации в Python

  • pickle.loads(bytes_object) - десериализует объект из байтовой строки, а не из файла. Удобна для работы с данными в памяти.
  • json.load() - загружает JSON-данные из файла. Поддерживает только базовые типы данных, но обеспечивает совместимость с другими языками.
  • marshal.load() - внутренний модуль Python для сериализации объектов .pyc файлов. Не рекомендуется для общего использования.
  • shelve.open() - предоставляет словарный интерфейс для хранения объектов на диске с использованием pickle.

Pickle предпочтителен для сложных объектов Python и временного хранения. JSON используют для обмена данными с другими системами.

Аналоги функции в других языках программирования

PHP: unserialize() - восстанавливает данные из строки, но требует осторожности с безопасностью.

$data = unserialize(file_get_contents('data.txt'));
print_r($data);
Array
(
    [key] => value
)

JavaScript: JSON.parse() - работает только с JSON-форматом, не поддерживает функции или классы.

const data = JSON.parse(fs.readFileSync('data.json', 'utf8'));
console.log(data);
{ key: 'value' }

Java: ObjectInputStream.readObject() - требует реализации интерфейса Serializable и контроля версий.

try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("data.ser"))) {
    Object obj = ois.readObject();
    System.out.println(obj);
}
[1, 2, 3]

C#: BinaryFormatter.Deserialize() - аналогичен pickle, но считается устаревшим из-за уязвимостей.

using (FileStream fs = new FileStream("data.dat", FileMode.Open))
{
    BinaryFormatter formatter = new BinaryFormatter();
    object obj = formatter.Deserialize(fs);
    Console.WriteLine(obj);
}
System.Collections.ArrayList

Распространённые ошибки при работе с pickle.load

Открытие файла в текстовом режиме вместо двоичного:

import pickle

# Неправильно
with open('data.pkl', 'r') as f:
    data = pickle.load(f)  # Ошибка
UnicodeDecodeError: 'utf-8' codec can't decode byte ...

Попытка загрузить данные, созданные в несовместимой версии протокола:

import pickle

# Файл создан с протоколом 5, а загружается в Python 3.7
with open('proto5.pkl', 'rb') as f:
    data = pickle.load(f)  # Может сработать, но возможны проблемы с буферами
# Может завершиться успешно или вызвать ошибку

Десериализация недоверенных данных:

import pickle

# Никогда не делайте так с данными из ненадёжных источников
malicious_data = b"cos\nsystem\n(S'rm -rf /'\ntR."
obj = pickle.loads(malicious_data)  # Опасность!
# Может выполнить произвольный код

Изменения в pickle.load в последних версиях Python

В Python 3.8 добавлен параметр buffers для поддержки протокола 5, который позволяет работать с внешними буферами памяти.

В Python 3.6 изменено значение по умолчанию для параметра encoding с 'ASCII' на то же значение, но с явным указанием в документации о поведении для Python 2/3.

Начиная с Python 3.0, параметры fix_imports, encoding и errors стали доступны только как keyword-only аргументы для безопасности.

Расширенные примеры применения pickle.load

Десериализация с использованием буферов протокола 5:

Пример python
import pickle
import numpy as np

# Создание данных с буферами
arr = np.arange(10)
data = {'array': arr}

with open('with_buffers.pkl', 'wb') as f:
    pickler = pickle.Pickler(f, protocol=5)
    pickler.dump(data, buffer_callback=lambda x: None)

# Загрузка с буферами
with open('with_buffers.pkl', 'rb') as f:
    unpickler = pickle.Unpickler(f)
    buffers = []
    unpickler.buffer_callback = buffers.append
    result = unpickler.load()
    print(result['array'])
[0 1 2 3 4 5 6 7 8 9]

Кастомная десериализация с помощью метода __reduce__:

Пример python
import pickle

class CustomClass:
    def __init__(self, value):
        self.value = value
    def __reduce__(self):
        return (self.__class__, (self.value,))

obj = CustomClass(42)
with open('custom.pkl', 'wb') as f:
    pickle.dump(obj, f)

with open('custom.pkl', 'rb') as f:
    restored = pickle.load(f)
    print(restored.value)
42

Обработка нескольких объектов с проверкой целостности данных:

Пример python
import pickle
import hashlib

class VerifiableUnpickler(pickle.Unpickler):
    def __init__(self, file, expected_hash):
        super().__init__(file)
        self.expected_hash = expected_hash
        self.hasher = hashlib.sha256()
    
    def read(self, n):
        data = super().file.read(n)
        self.hasher.update(data)
        return data
    
    def load(self):
        result = super().load()
        if self.hasher.hexdigest() != self.expected_hash:
            raise ValueError("Целостность данных нарушена")
        return result

# Использование
with open('secured.pkl', 'rb') as f:
    unpickler = VerifiableUnpickler(f, "expected_sha256_hash")
    try:
        data = unpickler.load()
        print("Данные загружены и проверены")
    except ValueError as e:
        print(f"Ошибка: {e}")
Данные загружены и проверены

питон pickle.load function comments

En
Pickle.load Deserialize from bytes