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

Использование pickle.dump для сохранения данных в Python
Раздел: Сериализация, Бинарная сериализация
pickle.dump(obj: Any, file: file-like object, protocol: int=None, *, fix_imports: bool=True): None

Функция pickle.dump() из стандартного модуля pickle предназначена для сериализации Python-объектов в байтовый поток. Сериализация преобразует объект в последовательность байтов, которую можно сохранить в файл или передать по сети, а затем восстановить с помощью pickle.load().

Общее описание

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

Аргументы функции

Сигнатура функции: pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None).

  • obj: Любой Python-объект, предназначенный для сериализации.
  • file: Файловый объект, открытый для записи в байтовом режиме (должен иметь метод write()).
  • protocol: Целое число, определяющее протокол сериализации. Доступные версии: 0 (человекочитаемый ASCII), 1 (старый бинарный), 2 (Python 2.3), 3 (Python 3.0), 4 (Python 3.4), 5 (Python 3.8). Значение -1 выбирает последнюю доступную версию. По умолчанию используется протокол 4 в Python 3.8 и выше.
  • fix_imports: При значении True и использовании protocol ≤ 2, pickle пытается сопоставить старые имена модулей Python 2 с новыми в Python 3.
  • buffer_callback: Функция обратного вызова, используемая для сериализации внешних буферов памяти (протокол 5).

Возвращаемое значение

Функция возвращает None. Сериализованные данные записываются в переданный файловый объект.

Примеры базового использования

Пример 1: Сохранение простого словаря в файл с протоколом по умолчанию.

import pickle

data = {'name': 'Alice', 'age': 30, 'city': 'Moscow'}
with open('data.pkl', 'wb') as f:
    pickle.dump(data, f)
print("Объект сериализован.")
Объект сериализован.

Пример 2: Явное указание протокола (например, протокол 3).

import pickle

data = [1, 2.5, "text", True]
with open('data_v3.pkl', 'wb') as f:
    pickle.dump(data, f, protocol=3)
print(f"Использован протокол 3.")
Использован протокол 3.

Пример 3: Сериализация нескольких объектов в один поток.

import pickle

with open('multi.pkl', 'wb') as f:
    pickle.dump(100, f)
    pickle.dump([10, 20, 30], f)
    pickle.dump({'key': 'value'}, f)
print("Записано несколько объектов.")
Записано несколько объектов.

Альтернативы в Python

Модуль json позволяет сериализовать объекты в текстовый формат JSON. Работает только со стандартными типами (словари, списки, строки, числа). Не поддерживает сериализацию произвольных Python-объектов.

Модуль marshal является низкоуровневым сериализатором, используемым для байт-кода Python. Не рекомендуется для общего применения.

Модуль shelve предоставляет персистентное хранилище объектов на основе pickle и DBM. Удобен для работы со словарём, который автоматически сохраняется на диск.

Сторонние модули, такие как dill или cloudpickle, расширяют возможности pickle для сериализации более сложных конструкций (лямбда-функций, локальных классов).

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

PHP: Функция serialize() создает строковое представление переменной.

$data = ["name" => "Bob", "age" => 25];
$serialized = serialize($data);
echo $serialized;
a:2:{s:4:"name";s:3:"Bob";s:3:"age";i:25;}

JavaScript (Node.js): Модуль v8 или Buffer для сериализации. Более распространена сериализация в JSON.

const v8 = require('v8');
const data = { x: 10, y: 'text' };
const serialized = v8.serialize(data);
console.log(serialized);
<Buffer  ff 0d 22 02 01 78 02 01 79 02 04 74 65 78 74 ...>

Java: Интерфейс java.io.Serializable и классы ObjectOutputStream/ObjectInputStream.

import java.io.*;

class Person implements Serializable {
    String name;
    int age;
}

Person p = new Person();
p.name = "Alice"; p.age = 30;
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.ser"))) {
    oos.writeObject(p);
}
Файл data.ser создан.

C#: Пространство имен System.Runtime.Serialization.Formatters.Binary и класс BinaryFormatter (не рекомендуется из-за уязвимостей). Альтернативы: System.Text.Json, XmlSerializer.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
class Person { public string Name; public int Age; }

var person = new Person { Name = "Tom", Age = 25 };
var formatter = new BinaryFormatter();
using (var stream = new FileStream("data.dat", FileMode.Create))
{
    formatter.Serialize(stream, person);
}
Файл data.dat создан.

Golang: Пакет encoding/gob для сериализации структур. Требует регистрации типов.

package main
import (
    "encoding/gob"
    "os"
)
type Data struct { Name string; Age int }
func main() {
    data := Data{"John", 40}
    file, _ := os.Create("data.gob")
    encoder := gob.NewEncoder(file)
    encoder.Encode(data)
    file.Close()
}
Файл data.gob создан.

Типичные ошибки

Ошибка 1: Попытка сериализации объекта, не поддерживающего сериализацию (например, открытого файла).

import pickle

with open('test.txt', 'r') as f:
    pickle.dump(f, open('error.pkl', 'wb'))
TypeError: cannot pickle '_io.TextIOWrapper' object

Ошибка 2: Запись в файл, открытый в текстовом, а не в бинарном режиме.

import pickle

data = [1, 2, 3]
with open('text_mode.pkl', 'w') as f:
    pickle.dump(data, f)
TypeError: write() argument must be str, not bytes

Ошибка 3: Использование разных протоколов для сериализации и десериализации без учёта совместимости (редко, но может привести к ошибкам).

Ошибка 4: Сериализация больших объектов без учёта ограничений безопасности (может привести к исчерпанию памяти).

Изменения в последних версиях

В Python 3.8 был добавлен протокол 5, который поддерживает внеполосные данные и функцию buffer_callback.

В Python 3.0 протокол по умолчанию изменился с 0 (ASCII) на 3 (бинарный). В Python 3.8+ протокол по умолчанию - 4.

Параметр fix_imports стал keyword-only в Python 3.

Устаревший аргумент bin (Python 2) был удалён.

Расширенные примеры

Пример 1: Сериализация пользовательского класса.

Пример python
import pickle

class User:
    def __init__(self, name, level):
        self.name = name
        self.level = level
    def __repr__(self):
        return f"User({self.name}, {self.level})"

user = User("Anna", 5)
with open('user.pkl', 'wb') as f:
    pickle.dump(user, f, protocol=4)

with open('user.pkl', 'rb') as f:
    loaded = pickle.load(f)
print(f"Загружен: {loaded}")
Загружен: User(Anna, 5)

Пример 2: Использование протокола 5 с buffer_callback для работы с большими массивами памяти.

Пример python
import pickle
import io

data = {'arr': memoryview(b'x' * 1000)}
buffers = []
def buffer_callback(buf):
    buffers.append(buf)

with open('with_buffers.pkl', 'wb') as f:
    pickle.dump(data, f, protocol=5, buffer_callback=buffer_callback)
print(f"Создано буферов: {len(buffers)}")
Создано буферов: 1

Пример 3: Сериализация в байтовую строку с помощью pickle.dumps (близкая функция).

Пример python
import pickle

obj = {'set': {1, 2, 3}, 'tuple': (5, 6)}
bytes_data = pickle.dumps(obj, protocol=4)
print(f"Тип данных: {type(bytes_data)}, длина: {len(bytes_data)}")

restored = pickle.loads(bytes_data)
print(f"Восстановленный объект: {restored}")
Тип данных: <class 'bytes'>, длина: 45
Восстановленный объект: {'set': {1, 2, 3}, 'tuple': (5, 6)}

Пример 4: Сериализация лямбда-функции с использованием модуля dill.

Пример python
import dill  # требует установки

func = lambda x: x * 2
with open('lambda.pkl', 'wb') as f:
    dill.dump(func, f)

with open('lambda.pkl', 'rb') as f:
    loaded_func = dill.load(f)
print(f"Результат работы функции: {loaded_func(21)}")
Результат работы функции: 42

питон pickle.dump function comments

En
Pickle.dump Serialize a Python object to a binary file