Двоичные форматы
Архивы
В стандартной библиотеке Python есть модули для работы с .zip
— zipfile
, для прочих открытых форматов архивов существует обертка к библиотеке libarchive[pip].
Работа с zip архивами через zipfile
.zip
архив состоит из сжатых (одним из 4 алгоритмов) файлов, к каждому из которых можно обратиться зная его уникальное имя (включающее путь), это имя и используется при распаковке (при необходимости создаются соответствующие папки).
Чтение
import zipfile
zobj = zipfile.ZipFile('test.zip')
lns = obj.namelist()
# lns == ['data/test1.txt', 'data/test2.txt']
fobj = zobj.open('data/file.txt')
# Файл всегда открывается в режиме binary!
s = fobj.read()
#s == b'Test zip file content'
fobj.close()
zobj.close()
Запись
Поддерживаются опции w
— перезапись архива, a
— дополнение архива (если архива нет, то он будет создан) и x
— дополнение архива (если архива нет, то будет выброшено исключение).
import zipfile
zobj = zipfile.ZipFile('test.zip', 'a')
zobj.writestr('test.txt', b'Testing data', zipfile.ZIP_DEFLATED)
zobj.close()
Флаг zipfile.ZIP_DEFLATED
необходим, иначе файл будет добавлен в архив без сжатия.
В архиве .zip
нельзя создать пустую папку и нельзя сохранить атрибуты папки. Файл из архива .zip
нельзя удалить, изменить или переименовать.
Кроме того zipfile
позволяет извлекать файлы из архива (extract
, extractall
), и добавлять их в архив по имени файла (write
). См. документацию.
Изображения
Обработка изображений дело ресурсоемкое, поэтому библиотеки Python для работы с картинками обычно имеют высокоуровневый интерфейс, под которым прячется начинка на C. Рассмотрим работу с картинками на примере библиотеки Pillow
[pip].
Библиотека загружает и хранит изображение в памяти целиком в одном из поддерживаемых типов массивов. Вот некоторые популярные типы массивов:
Тип | Байт на пиксель | Описание |
---|---|---|
1 | 1 | Монохромное изображение |
L | 1 | В оттенках серого |
RGB | 3 | Цветное изображение без прозрачности |
RGBA | 4 | Цветное изображение c прозрачностью |
HSV | 3 | Кодирование Тон-Яркость-Значение |
Чтение
Поддерживаемых форматов очень много.
from PIL import Image
# Открытые файла
im = Image.open("test.png")
im.load() # Отложенное чтение
# Создание нового изображения
im = Image.new("RGB", (100,100))
# Создание изображения из массива
im = Image.frombytes("L", (100,100), data)
Рисование
from PIL import Image, ImageDraw, ImageFont
im = Image.open("test.png")
# Создание объекта для рисования
draw = ImageDraw.Draw(im)
# Рисование
draw.line((0, 0) + im.size, fill=128)
font = ImageFont.truetype("arial.ttf", 15)
draw.text((40,40),"Привет!",font=font)
# Размер изображения
s = im.size
# s == (100, 100)
Запись
from PIL import Image
im = Image.open("test.png")
# Преобразуем тип данных
mim = im.convert('L')
# Просмотр
mim.show()
# Получаем байты в соответствии с типом
bs = mim.tobytes()
# bs = b'&\x00\x00\x00\x00\x00\x00\x00\x00...
# Сохраняем файл
mim.save("test.bmp")
Если нужно получить закодированное в заданном формате (.bmp
, .jpg
) изображение, то методу save
надо подложить io.BytesIO
объект и указать формат через аргумент format
.
Офисные документы
Офисные документы можно относительно просто читать и создавать с помощью этих библиотек.
Расширение | Название | Модуль |
---|---|---|
.docx | MS Office 2007 Word | python-docx[pip] |
.xls | MS Office 1997 Excel | xlrd[pip], xlwt[pip] |
.xlsx | MS Office 2007 Excel | openpyxl[pip] |
.odt | OpenDocument Text | odfpy[pip] |
.ods | OpenDocument SpreadSheet | odfpy[pip] |
.pdf | Portable Document Format | reportlab[pip] |
.svg | Scalable Vector Graphics | svgwrite[pip] |
Однако схема «открыл → изменил → сохранил» может вызывать проблемы. В этих случаях лучше использовать API офисных пакетов.
Чтение электронных таблиц XLSX
from openpyxl import load_workbook
wb = load_workbook("sample.xlsx")
ws = wb.active # Выбор листа
print(ws['A1'].value) # С использованием Excel нотации
print(ws.cell(1, 1).value) # По индексу сроки/столбца
for row in ws.rows: # По всем строкам на листе
print(row[0].value, row[1].value)
Запись электронных таблиц XLSX
from openpyxl import Workbook
wb = Workbook()
ws = wb.active # Выбор листа
ws['A1'] = 42 # С использованием Excel нотации
ws.cell(1, 1, 42) # По индексу сроки/столбца
wb.save("sample.xlsx")
Чтение NetCDF4
from netCDF4 import Dataset
#https://www.unidata.ucar.edu/software/netcdf/examples/sresa1b_ncar_ccsm3-example.nc
ncdata = Dataset("sresa1b_ncar_ccsm3-example.nc", format="NETCDF4")
print(ncdata.variables.keys()) # Обзор всех переменных
# Основная переменная:
print(ncdata['ua'].shape) # (1, 17, 128, 256)
# Оси:
print(ncdata['plev'].shape) # (17,)
print(ncdata['lat'].shape) # (128,)
print(ncdata['lon'].shape) # (256,)
# Чтение данных:
plev = ncdata['plev'][:]
lat = ncdata['lat'][:]
lon = ncdata['lon'][:]
ua = ncdata['ua'][:]
#Конкретная точка
print(plev[1],lat[20],lon[20],ua[0,1,20,20])
Что еще нужно знать о работе с двоичными форматами
- Структура произвольного двоичного формата обычно описывается в виде C-структур, поэтому читать такие файлы целесообразно с использованием
cffi
,ctypes
илиstruct
. - Иногда встречаются беззаголовочные бинарные файлы. Например результаты работы регистратора.
- Формат некоторых двоичный файлов неизвествен и/или охраняется как объект авторского права.
- В идеальном случае спецификация формата известна, в этом случае практически наверняка есть открытая библиотека для работы с такими файлами.
- Некоторые форматы могут иметь собственные версии.
- Могут возникать проблемы совместимости между различными версиями программ/библиотек для чтения и записи файлов.