第12章 データ圧縮、アーカイブと永続化¶
12.1 gzip 圧縮ファイルを扱う gzip¶
gzip形式のファイル圧縮・展開 (gzip, gunzip コマンドと同等)
-
gzip ファイルを圧縮、展開する
関数名 解説 戻り値 open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None)gzip形式のファイルを開き、ファイルオブジェクトを返す
読み込みモードなら既存のファイルを開き、書き込みモードならファイル作成する(*1)gzip.GzipFile compress(data, compresslevel=9, *, mtime=None)指定されたデータを gzip 圧縮する
データは bytes 型である必要があるbytes decompress(data)指定された gzip 圧縮されたデータを展開し bytes オブジェクトを返す bytes -
(*1) gzip 仕様は追記に対応しておらず、open() の
modeに追記 (a等) を指定しても、新規書き込みとして扱われる>>> import gzip >>> with gzip.open("sample.gz", "wt") as f: ... f.write("適当な文字列。" * 10) ... 70適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。>>> with gzip.open("sample.gz", "wt") as f: ... f.write("\n適当な文字列。" * 10) ... 80適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 適当な文字列。 -
圧縮、解凍
>>> text = "適当な文字列。" * 10 >>> text '適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な 文字列。適当な文字列。' >>> len(text) 70 >>> btext = text.encode("utf-8") # bytes 型へ >>> len(btext) 210 >>> comp = gzip.compress(btext) # 圧縮 >>> len(comp) 46 >>> decomp = gzip.decompress(comp) # 解凍 >>> len(decomp) 210 >>> btext == decomp # bytes 型で同値 True >>> decomptext = decomp.decode("utf-8") >>> len(decomptext) 70 >>> decomptext '適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な文字列。適当な 文字列。適当な文字列。' >>> decomptext == text # str 型で同値 True
-
12.2 ZIP ファイルを扱う zipfile¶
ZIP形式でアーカイブされたファイルを扱う
- ZIP ファイルを操作する
-
class
ZipFile(file, mode='r' compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timstamps=True)-
file対象となる ZIP アーカイブ (ファイル名や path-like オブジェクト) -
mode-
r読み込み、w新規作成(既存を削除)、a追記、x新規作成(既存はエラー)
-
-
compressionZIP 圧縮方法-
ZIP_DEFLATEDzlib モジュール必要 -
ZIP_BZIP2bz2 モジュール必要 -
ZIP_LZMAlzma モジュール必要
-
-
allowZip64True の場合、4GiB 以上の ZIP ファイル作成に ZIP64 形式にする -
compresslevel圧縮レベル- ZIP_DEFLATED : 0-9
- ZIP_BZIP2 : 1-9
-
strict_timestampsFalse の場合、1980 年より前のタイムスタンプを 1980-01-01 に、2108年以降のタイムスタンプを 2107-12-31 に設定する - 戻り値 zipfile.ZipFile
-
-
関数
is_zipfile(filename)-
filenameファイル名、path-like オブジェクト - 戻り値 bool
-
-
ZipFileオブジェクトのメソッドメソッド名 解説 戻り値 infolist()ZipInfoのリストを返すlist namelist()アーカイブされているファイル名のリストを返す list getinfo(name)指定されたファイルの ZipInfoを返すZipInfo open(name, mode='r', pwd=None, *, force_zip64=None)指定したファイルを開く (コンテキストマネージャー) ZipExtFile extract(member, path=None, pwd=None)指定 (ファイル名、ZipInfo) されたファイルを展開し、パスを返す str extractall(path=None, members=None, pwd=None)全ファイルを展開する None read(name, pwd=None)指定されたファイルの中身を返す bytes write(filename, arcname=None, compress_type=None)指定したファイルを ZIP ファイルへ書き込む arcnameを指定の場合、その名前でアーカイブされるNone writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)指定したファイル名に対してデータ (str または bytes) を書き込む None close()ZipFileを閉じるNone -
write()writestr()の引数compress_typeの値は、ZipFileのパラメータcompressionと同じ選択肢で、メソッドでの指定が優先される
-
-
ZipInfoクラスは、ZIP ファイル内の1ファイル (ディレクトリ含む) の情報属性名、メソッド名 解説 戻り値 filenameファイル名 str date_time最終更新日時 (6要素タプル) tuple compress_size圧縮後サイズ int file_size圧縮前サイズ int is_dir()ディレクトリの場合、True bool -
ZipExtFileクラスは、読み取り専用の file-like オブジェクトメソッド名 解説 戻り値 read(size=-1, /)指定バイト数まで読み出す bytes readline(size=-1, /)指定バイト数、行末までの小さい方まで読み出す bytes readlines(hint=-1, /)指定行数まで読み出し、行のリストを返す
※通常、行処理にはfor line in file:を使用するlist seek(offset, whence=os.SEEK_SET, /)(略) int tell()(略) int >>> import zipfile >>> zipfile.is_zipfile('python-3.9.4-docs-text.zip') # ZIPファイルかチェック True >>> zip = zipfile.ZipFile('python-3.9.4-docs-text.zip') # ZIPファイルを開く >>> len(zip.namelist()) # ファイル数を確認 505 >>> zip.namelist()[:2] # 先頭2件のファイル名を取得 ['python-3.9.4-docs-text/', 'python-3.9.4-docs-text/contents.txt'] >>> with zip.open('python-3.9.4-docs-text/contents.txt') as f: # ファイルを開く ... contents = f.read() ... >>> contents[:40] # 先頭の40文字を確認 b'Python Documentation contents\n**********'>>> for name in zip.namelist(): # zipfileモジュールのドキュメントを探す ... if 'zipfile' in name: ... zipfile_doc = name ... break ... >>> zipfile_doc # ファイル名を確認 'python-3.9.4-docs-text/library/zipfile.txt' >>> zipfile_info = zip.getinfo(zipfile_doc) # ZipInfoを取得 >>> zipfile_info.date_time # 最終更新日を確認 (2021, 4, 10, 12, 7, 54) >>> zip.extract(zipfile_info) # zipfileのマニュアルを展開する '/Users/takanori/python-3.9.4-docs-text/library/zipfile.txt'>>> with zipfile.ZipFile('example.zip', mode='w', zipfile.ZIP_DEFLATED) as wzip: ... wzip.write('spam.txt') # ファイルを追加する ... wzip.write('ham.txt', 'hamham.txt') # ファイルを別名で追加する ... wzip.writestr('eggs.txt', 'たまご') # ファイル名を指定しテキストを直接書き込む ... wzip.namelist() # ファイルを確認する ... ['spam.txt', 'hamham.txt', 'eggs.txt'] >>> zipfile.is_zipfile('example.zip') # 正しいZIPファイルかを確認 True
-
12.3 tar ファイルを扱う tarfile¶
gzip, bz2, lzma 形式で圧縮されたものを含む、tar 形式アーカイブを読み書きする
- tar ファイルを操作する
-
関数
open(name=None, mode='r', fileobj=None, bufsize=20240, **kwargs)-
nametar ファイルのファイル名 -
modeモード指定rw等- 圧縮形式を指定する場合は
r:gzw:xz等 (非圧縮指定はw:等) - 読み込み時は
rだけでも、ファイル名拡張子から圧縮形式が自動判定される - 圧縮ファイルは追記モードが使用できない (
aa:のみ)
- 圧縮形式を指定する場合は
-
fileobjtar ファイルのファイルオブジェクト -
bufsizeブロックサイズ (デフォルトでよい) -
戻り値
tarfile.TarFile
-
-
関数
is_tarfile(name)-
nameファイル名、または file-like オブジェクト - 戻り値 (bool) 指定ファイルが tar 形式アーカイブなら True
-
-
TarFileオブジェクトのメソッドメソッド名 解説 戻り値 getnames()tar ファイル内にアーカイブされているファイル名リスト list getmember(name)指定ファイル名の TarInfoを返すTarInfo getmembers()tar ファイル内にアーカイブされている全ファイルの TarFileのリストを返すlist extract(member, path="", set_attrs=True, *, numeric_owner=False)指定ファイルを指定場所へ展開 member:ファイル名またはTarInfoNone extractall(path="", set_attrs=True, *, numeric_owner=False)全ファイルを指定場所へ展開 None extractfile(member)指定ファイルを開き、ファイルオブジェクトを返す member:ファイル名またはTarInfoファイルオブジェクト add(name, arcname=None, recursive=True, exclude=None, *, filter=None)指定ファイルを tar ファイルのアーカイブへ追加する arcnameを指定するとそのファイル名で追加
ディレクトリ指定では再帰追加可能? close()None >>> import tarfile >>> with tarfile.open("./testarchive.tar", "w:gz") as f: ... f.add("./inArchive1.txt") ... >>> with tarfile.open("./testarchive.tar") as f: ... f.getnames() ... f.getmembers() ... ['./inArchive1.txt'] [<TarInfo './inArchive1.txt' at 0x140b4104640>] >>> with tarfile.open("./testarchive.tar") as f: ... with f.extractfile("./inArchive1.txt") as elem: ... elem.read().decode("sjis") ... 'アーカイブ内ファイル1' >>> with tarfile.open("./testarchive.tar") as f: ... info = f.getmember("./inArchive1.txt") ... info ... print(f"{info.name=}, {info.size=}, {info.mtime=}, {info.mode=:o}") ... <TarInfo './inArchive1.txt' at 0x140b4104940> info.name='./inArchive1.txt', info.size=22, info.mtime=1753410842.0, info.mode=666 >>> with tarfile.open("./testarchive.tar") as f:
-
12.4 Python オブジェクトをシリアライズする pickle¶
Python オブジェクトをファイル等に保存可能なバイト列に変換 (pickle 化 という)、復元 (非 pickle 化 という) する
-
JSON へのシリアライズ方法である json モジュールとの比較
- JSON は文字列だが、pickle はバイナリ
- JSON は他のプログラミング言語でも利用可能だが、pickle は Python 固有フォーマット
- JSON は文字列、数値など一部のデータ型のみ扱うが、pickle は Python の様々なオブジェクトを扱える
-
Python オブジェクトのシリアライズとデシリアライズ
関数名 解説 戻り値 dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)オブジェクトをシリアライズしてファイルへ保存する None dumps(obj, protocol=None, *, fix_import=True, buffer_callback=None)オブジェクトをシリアライズしてバイト列を返す bytes load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)ファイルの中身をデシリアライズし、結果オブジェクトを返す object loads(data, /, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)バイト列をデシリアライズし、結果オブジェクトを返す object dumps, loads (bytes でのやり取り) の例
>>> import pickle >>> from datetime import datetime >>> now = datetime.now() >>> data = {"NOW-date": now} # 値が datetime の辞書データ作成 >>> type(data) <class 'dict'> >>> data {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} >>> serialized = pickle.dumps(data) # シリアライズ >>> serialized b'\x80\x04\x958\x00\x00\x00\x00\x00\x00\x00}\x94\x8c\x08NOW-date\x94\x8c\x08datetime\x94\x8c\x08datetime\x94\x93\x94C\n\x07\xe9\x07\x19\x10\x04\x00\x03\x14S\x94\x85\x94R\x94s.' >>> desirialized = pickle.loads(serialized) # デシリアライズ >>> type(desirialized) <class 'dict'> >>> desirialized # 元のデータを復元できている {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}dump, load (ファイルでのやり取り) の例
>>> data # 対象データ {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)} >>> with open("nowdate.pkl", "wb") as f: ... pickle.dump(data, f) # シリアライズしてファイルへ書き込み ... >>> with open("nowdate.pkl", "rb") as f: ... obj = pickle.load(f) # ファイル内容をデシリアライズ ... >>> obj # 復元を確認 {'NOW-date': datetime.datetime(2025, 7, 25, 16, 4, 0, 201811)}dump()で生成されたファイルの様子

- ※ pickle 化にはプロトコルのバージョンが 0 から 5 まであり、新しいバージョンで pickle 化されたオブジェクトは古いバージョンで非 pickle 化できない (
pickle.DEFAULT_PROTOCOLでデフォルト確認可能)
- ※ pickle 化にはプロトコルのバージョンが 0 から 5 まであり、新しいバージョンで pickle 化されたオブジェクトは古いバージョンで非 pickle 化できない (
Tatsuya ISHIGAKI さんが5ヶ月前に更新 · 4件の履歴