1.6Kпросмотров
37.2%от подписчиков
1 февраля 2026 г.
Score: 1.8K
🗜 Сжатие данных на лету: gzip, lzma (работа со сжатыми файлами) Когда логи занимают гигабайты, а дампы БД не помещаются на диск, сжатие становится must-have. Но не нужно сжимать вручную — Python умеет работать со сжатыми файлами напрямую, как с обычными. ⚡️ gzip: стандарт для логов и JSON Модуль gzip даёт тот же интерфейс, что и open(), но прозрачно сжимает: import gzip import json # ПИШЕМ сжатый JSON одной строкой with gzip.open('data.json.gz', 'wt', encoding='utf-8') as f: json.dump({'users': [{'id': i, 'name': f'user_{i}'} for i in range(10000)]}, f) # Файл data.json.gz весит в 5-10 раз меньше # ЧИТАЕМ как обычный файл with gzip.open('data.json.gz', 'rt', encoding='utf-8') as f: data = json.load(f) print(f"Загружено {len(data['users'])} пользователей") # 10000 ➡️ Режимы: 'rt'/'wt' для текста, 'rb'/'wb' для бинарных данных. Сжатие происходит на лету — не нужно держать в памяти весь несжатый файл. ✅ lzma: максимальное сжатие (но медленнее) Для архивов, где важна степень сжатия, а не скорость: import lzma import pickle # Сохраняем сжатый pickle data = [{'x': i, 'y': i2} for i in range(100000)] with lzma.open('data.pickle.xz', 'wb') as f: pickle.dump(data, f) print("Файл сохранён с максимальным сжатием") # Загружаем обратно with lzma.open('data.pickle.xz', 'rb') as f: loaded = pickle.load(f) print(f"Загружено {len(loaded)} объектов") ➡️ lzma (формат .xz) сжимает лучше gzip, но работает медленнее. Идеально для долгосрочного хранения дампов. 🔍 Сравниваем gzip vs lzma на практике import gzip, lzma, os import random # Генерируем тестовые данные (повторяющиеся строки хорошо сжимаются) text = '\n'.join(str(random.randint(1000, 9999)) for _ in range(50000)) # Сохраняем в разных форматах with open('raw.txt', 'w') as f: f.write(text) with gzip.open('test.gz', 'wt') as f: f.write(text) with lzma.open('test.xz', 'wt') as f: f.write(text) # Сравниваем размеры for name in ['raw.txt', 'test.gz', 'test.xz']: print(f"{name}: {os.path.getsize(name)} байт") # raw.txt: 345678 байт # test.gz: 45678 байт (в ~7.5 раз меньше) # test.xz: 23456 байт (в ~14.7 раз меньше) ➡️ lzma сжимает в 2-3 раза эффективнее gzip, но занимает больше CPU и времени. Выбирай по ситуации. 🧪 Контекстный менеджер для прозрачного сжатия Создадим универсальный инструмент, который сам определяет формат по расширению: import bz2 # ещё один формат сжатия def smart_open(filename, mode='r', kwargs): """Открывает файл, автоматически определяя сжатие по расширению.""" if filename.endswith('.gz'): return gzip.open(filename, mode, kwargs) elif filename.endswith('.xz') or filename.endswith('.lzma'): return lzma.open(filename, mode, kwargs) elif filename.endswith('.bz2'): return bz2.open(filename, mode, kwargs) else: return open(filename, mode, kwargs) # Используем единообразно with smart_open('data.json.gz', 'rt') as f: data = json.load(f) with smart_open('dump.sql', 'w') as f: f.write('SELECT * FROM users;') ➡️ Один интерфейс для всех типов файлов - код становится чище. 🚀 Потоковое сжатие сетевых данных Сжимаем данные прямо при передаче по сети или в пайплайнах: import gzip import io def compress_chunks(chunks): """Сжимает поток чанков на лету.""" buffer = io.BytesIO() with gzip.GzipFile(fileobj=buffer, mode='wb') as f: for chunk in chunks: f.write(chunk.encode() if isinstance(chunk, str) else chunk) buffer.seek(0) return buffer # Пример: сжимаем логи построчно log_lines = [f"[INFO] Event {i}\n" for i in range(1000)] compressed = compress_chunks(log_lines) # Результат уже сж
1.6K
просмотров
4000
символов
Да
эмодзи
Нет
медиа

Другие посты @pytstart

Все посты канала →
🗜 Сжатие данных на лету: gzip, lzma (работа со сжатыми файл — @pytstart | PostSniper