Python で .zip
や .tar.gz
などのアーカイブファイル(圧縮ファイル)を扱う方法についてかんたんにまとめました。
仕様と動作の確認に使用した Python のバージョンは Python 3.9.x です。
Python 2 が主流の頃から Python を使い続けてきた方は、アーカイブファイルの操作といえば標準ライブラリの zipfile
や tarfile
などが真っ先に思い浮かぶ方が多いのではないかと思います。
Python 3 の場合は zipfile
や tarfile
を使うのもよいですがより高レベルの shutil
を使うという選択肢もあります。
shutil
は zipfile
や tarfile
よりもシンプルでわかりやすい(そしてアーカイブ形式によらず共通の)インタフェースを提供しています。
Python 3 でアーカイブファイルの操作が必要になったときは、まず最初に shutil
が使えないか検討し、使えたら shutil
を使い、使えない場合は zipfile
や tarfile
を使う、とするのがよいのではないかと思います。
それぞれの使い方をかんたんに見てみましょう。
shutil
shutil
は .zip
と .tar.gz
に対応しています 1 。
両者を共通のシンプルなインタフェース(=関数)で扱えます。
アーカイブファイルを作成する
関数 shutil.make_archive()
を使用します。
from shutil import make_archive
# .zip の場合
file_path = make_archive(base_name="/tmp/archived", format="zip", root_dir="/tmp/directory_to_archive")
# => `/tmp/archived.zip`
# .tar.gz の場合
file_path = make_archive(base_name="/tmp/archived", format="gztar", root_dir="/tmp/directory_to_archive")
# => `/tmp/archived.tar.gz`
各引数の意味合いは次のとおりです:
base_name
: 生成したいアーカイブファイルのパス(拡張子なし)format
: アーカイブフォーマットroot_dir
: アーカイブしたいディレクトリのパス
format
に "zip"
を選べば .zip
ファイル、 "gztar"
を選べば .tar.gz
ファイルが作成されます。
format
の選択肢にどのようなものがあるのかは環境により異なり shutil.get_archive_formats()
で調べることができます。
私の手元の環境では 5 つのフォーマットが利用可能でした:
shutil.get_archive_formats()
# =>
# [
# ('bztar', "bzip2'ed tar-file"),
# ('gztar', "gzip'ed tar-file"),
# ('tar', 'uncompressed tar file'),
# ('xztar', "xz'ed tar-file"),
# ('zip', 'ZIP file'),
# ]
これらの引数のうち root_dir
は非必須で、指定しなかった場合はカレントディレクトリがアーカイブ対象になります。
make_archive()
には他にも多くの引数があるので、実際に使うときには一度確認することをおすすめします。
shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])
make_archive()
の戻り値は実際に生成されたアーカイブファイルのパス( str
)です。
引数 base_name
に format
に対応した拡張子が付与されたものになります。
アーカイブファイルを展開する
関数 shutil.unpack_archive()
を使用します。
from shutil import unpack_archive
# .zip の場合
unpack_archive(filename="/tmp/archived.zip", extract_dir="/tmp/extracted", format="zip")
# .tar.gz の場合
unpack_archive(filename="/tmp/archived.tar.gz", extract_dir="/tmp/extracted", format="gztar")
各引数の意味合いは次のとおりです:
filename
: 展開したいアーカイブファイルのパスextract_dir
: 展開先のディレクトリのパスformat
: アーカイブフォーマット
このうち必須なのは filename
だけで、 extract_dir
と format
は非必須です。
extract_dir
を渡さなかった場合、展開先はカレントディレクトリになります。
format
を渡さなかった場合、 filename
の拡張子に合ったフォーマットが自動的に選択されます。
unpack_archive()
の引数は( Python 3.9 では)この 3 つのみです。
shutil.unpack_archive(filename[, extract_dir[, format]])
unpack_archive()
に戻り値はありません(戻り値 None
です)。
zipfile
from zipfile import ZipFile
アーカイブファイルを作成する
zipfile.ZipFile
オブジェクトのメソッド write()
writestr()
などを使用します。
`ZipFile()
ファイルをアーカイブファイルに格納する:
# サンプルファイルを用意
with open("/tmp/sample.txt", "w") as f:
f.write("はい、タケコプター!")
with ZipFile(file="/tmp/archived.zip", mode="w") as myzip:
myzip.write(filename="/tmp/sample.txt", arcname="sample.txt")
文字列を直接アーカイブファイルに格納する:
with ZipFile(file="/tmp/archived.zip", mode="w") as myzip:
myzip.writestr(zinfo_or_arcname="sample.txt", data="はい、どこでもドア!")
ZipFile()
の引数 mode
w
は書き込みモードを意味します。
w
の他に a
(追加モード)、 x
(排他的な書き込みモード)もあります。
アーカイブファイルを展開する
zipfile.ZipFile
オブジェクトのメソッド read()
extract()
extractall()
などを使用します。
個別の中身だけ読み込む:
with ZipFile(file="/tmp/archived.zip", mode="r") as myzip:
data = myzip.read(name="sample2.txt")
ファイルを 1 つ取り出す:
with ZipFile(file="/tmp/archived.zip", mode="r") as myzip:
myzip.extract(member="sample2.txt", path="/tmp/extracted")
中身をすべて取り出す:
with ZipFile(file="/tmp/archived.zip", mode="r") as myzip:
myzip.extractall(path="/tmp/extracted")
ZipFile()
の引数 mode
r
は読み込みモードを意味します。
展開せずに中身を確認する
zipfile.ZipFile
オブジェクトのメソッド infolist()
namelist()
などを使用します。
with ZipFile(file="/tmp/archived.zip", mode="r") as myzip:
infolist = myzip.infolist()
print(infolist) # -> list[ZipInfo]
tarfile
import tarfile
アーカイブファイルを作成する
tarfile.TarFile
オブジェクトのメソッド add()
addfile()
などを使用します。
tarfile.TarFile
オブジェクトは tarfile.open()
のコンテキストマネージャで取得できます。
ファイルをアーカイブファイルに格納する:
# サンプルファイルを用意
with open("/tmp/sample.txt", "w") as f:
f.write("はい、タケコプター!")
with tarfile.open(name="/tmp/archived.tar.gz", mode="w:gz") as mytar:
mytar.add(name="/tmp/sample.txt", arcname="sample.txt")
文字列を直接アーカイブファイルに格納する:
import io
text = "はい、カムカムキャット!".encode("utf8")
with tarfile.open(name="/tmp/archived.tar.gz", mode="w:gz") as mytar:
tarinfo = tarfile.TarInfo("sample.txt")
tarinfo.size = len(text)
fileobj = io.BytesIO(text)
mytar.addfile(tarinfo, fileobj)
tarfile.open()
の引数 mode
の w:gz
は書き込みモードで gzip
を意味します。
アーカイブファイルを展開する
tarfile.TarFile
オブジェクトのメソッド extract()
extractfile()
extractall()
などを使用します。
個別の中身だけ読み込む:
with tarfile.open(name="/tmp/archived.tar.gz", mode="r:gz") as mytar:
fileobj = mytar.extractfile("sample.txt")
data = fileobj.read()
ファイルを 1 つ取り出す:
with tarfile.open(name="/tmp/archived.tar.gz", mode="r:gz") as mytar:
mytar.extract(member="sample.txt", path="/tmp/extracted")
中身をすべて取り出す:
with tarfile.open(name="/tmp/archived.tar.gz", mode="r:gz") as mytar:
mytar.extractall(path="/tmp/extracted")
tarfile.open()
の引数 mode
の r:gz
は読み込みモードで gzip
を意味します。
展開せずに中身を確認する
tarfile.TarFile
オブジェクトのメソッド next()
getmembers()
getnames()
などを使用します。
1 件ずつ取得する:
with tarfile.open(name="/tmp/archived.tar.gz", mode="r:gz") as mytar:
while (tarinfo := mytar.next()):
print(tarinfo.name) # -> str
全件取得する:
with tarfile.open(name="/tmp/archived.tar.gz", mode="r:gz") as mytar:
members = mytar.getmembers()
print(members) # -> list[TarInfo]
コマンドラインで使用する
zipfile
モジュールと tarfile
モジュールは python -m
でコマンドラインから使用することもできます。
どちらも共通のオプションを提供しています。
-c
: 作成-e
: 展開-l
: 確認-t
: ファイルが壊れていないかどうかのチェック
zipfile
# 作成する
python -m zipfile -c monty.zip spam.txt eggs.txt
# 展開する
python -m zipfile -e monty.zip target-dir/
# 中身を確認する
python -m zipfile -l monty.zip
tarfile
# 作成する
python -m tarfile -c monty.tar spam.txt eggs.txt
# 展開する
python -m tarfile -e monty.tar other-dir/
# 中身を確認する
python -m tarfile -l monty.tar
まとめ
ということで、 Python で .zip
や .tar.gz
などのアーカイブファイル(圧縮ファイル)を扱う方法のまとめでした。
ライブラリ | 作成 | 展開 | 確認 |
---|---|---|---|
shutil |
make_archive() |
unpack_archive() |
(なし) |
zipfile |
ZipFile(file, mode="w") |
ZipFile(file, mode="r") |
ZipFile(file, mode="r") |
tarfile |
tarfile.open(file, mode="w:gz") |
tarfile.open(file, mode="r:gz") |
tarfile.open(file, mode="r:gz") |
参考
shutil
— High-level file operations — Python 3 documentationtarfile
— Read and write tar archive files — Python 3 documentationzipfile
— Work with ZIP archives — Python 3 documentation
- 正確には
.zip
にはzlib
モジュールが、.tar.gz
にはzlib
モジュールがそれぞれ利用できる必要があります。また、対応するモジュールが利用できる環境ではtar.bz2
やtar.xz
など他のアーカイブ形式にも対応しています。↩