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:
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__:
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
Обработка нескольких объектов с проверкой целостности данных:
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}")Данные загружены и проверены