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: Сериализация пользовательского класса.
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 для работы с большими массивами памяти.
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 (близкая функция).
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.
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