みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
初心者向け&Windowsユーザー向けPythonでZIP圧縮をするツールの作り方をお伝えしています。
前回の記事はコチラ。
ファイルをZIP形式に圧縮する方法をお伝えしました。
ただ、ZIPファイルに圧縮するのは単一ファイルではなくて、複数のファイルが望ましいですよね。
そして、あわよくば特定のフォルダ配下をその構造のままごっそり圧縮したいわけです。
そのためには、フォルダの中のサブフォルダとファイルのツリー構造を全て洗い出す必要があり、工夫してプログラムをしなくてはならない気がするのですが、そこはさすがのPython。
たった一つのos.walk関数でそれを解決しちゃいます。
ということで、今回はPythonでフォルダ内のツリー構造を走査してサブフォルダとファイルを全てリストアップする方法をお伝えします。
前回のおさらいと今回のお題
前回紹介したスクリプトはこちらでした。
import zipfile
with zipfile.ZipFile('test.zip','w') as myzip:
myzip.write('test.csv')
zipfileモジュールのZipFile関数とwriteメソッドを使って、ファイルをZIP圧縮するスクリプトです。
フォルダを丸ごとZIP圧縮したい
例えば、以下のようなフォルダ構造のフォルダが、スクリプトファイルと同階層にあるとします。
test
┗test1
┗test1.csv
┗test2
┗test2-1.csv
┗test2-2.csv
そこで、ほのかな期待を込めて、前述のスクリプトの3行目、write関数の引数を、この同階層のフォルダ名にしたらいけるのではないかと、作ってみました。
import zipfile
with zipfile.ZipFile('test.zip','w') as myzip:
myzip.write('test')
実行してみますと…
残念ながらtestフォルダの中身は空っぽ…
つまり、指定したフォルダのみしかZIPファイルに追加されないんですね。
これは別の方法を考える必要があります。
os.walk関数でフォルダのツリー構造を走査する
そこで登場するのが、指定したフォルダ配下のツリー構造を走査するos.walk関数です。
書き方はこちらです。
rootには走査するフォルダを指定します。
すると、os.walk関数はroot配下のツリーに含まれるすべてのフォルダについてタプルを生成します。ちなみに、タプルというのは、変更ができないリストのことで、以下のような内容です。
これら3つが何者かというと
- folder:フォルダ
- subfolders:そのフォルダに含まれるサブフォルダのリスト
- files:そのフォルダに含まれるファイルのリスト
です。
つまり、生成された各タプルについて、その中身を見ていけば、全てのサブフォルダとファイルを一覧することができるということです。
os.walk関数で生成されたタプルについて繰り返し処理をする
で、その方法なのですが、おなじみfor文を使います。os.walk関数で取得した全てのタプルについて繰り返し処理をするには、以下のように書きます。
#処理
こうすることで、毎回の繰り返しの中で、タプルの要素であるfolder、subfolders、filesを取り出すことができます。
Pythonのfor文の万能さが光りますね…
フォルダ構造を出力するスクリプト
では、先ほどのフォルダ「test」に対して、以下のようなスクリプトを作成してみました。
import os
for folder, subfolders, files in os.walk('test'):
print('folder: {}'.format(folder))
print('subfolders: {}'.format(subfolders))
print('files: {}'.format(files))
print()
os.walk関数で取得した各タプルの内容を出力する内容ですが、なかなかシンプルに書けました。
実行してみましょう。
バッチリですね。
そして、サブフォルダとファイルはリストで取得できていますから、さらにfor文を使えば全てのサブフォルダとファイルが取り出せそうです。
まとめ
以上、Pythonでフォルダ内のサブフォルダとファイルを全てリストアップする方法についてお伝えしました。
本来であれば、再帰的な処理を組む必要があるようなところなのですが、os.walk関数のおかげでとってもラクチンです。
他のツールを作るときにも活躍してくれそうです。
では、次回ですが全てのサブフォルダとファイルをZIPファイルに追加していきたいと思います。
どうぞお楽しみに!