Pythonでディレクトリのサイズを一覧表示する
概要
Pythonで、ディレクトリのサイズを一覧表示するプログラムを作成していきます。
Python、pathlibモジュールを使うでも紹介した、pathlib
モジュールを利用して作成します。
見た目
python main.py
.idea 8.1 KiB
main.py 1.8 KiB
ソースコード
from pathlib import Path
SUFFIXES = {
1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
}
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
"""Convert a file size to human-readable form.
http://diveintopython3-ja.rdy.jp/your-first-python-program.html
Keyword arguments:
size -- file size in bytes
a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024
if False, use multiples of 1000
Returns: string
"""
if size < 0:
raise ValueError('number must be non-negative')
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
for suffix in SUFFIXES[multiple]:
size /= multiple
if size < multiple:
return '{0:.1f} {1}'.format(size, suffix)
raise ValueError('number too large')
def _get_size(path_obj):
"""そのパスのサイズを返す。
Pathオブジェクトを受け取ります。
ファイルだった場合はそのファイルサイズを、
ディレクトリだった場合は再帰的に取得したファイルサイズを返します。
"""
if path_obj.is_file():
return path_obj.stat().st_size
elif path_obj.is_dir():
return sum(_get_size(p) for p in path_obj.iterdir())
def get_size(target_path='.'):
"""Pathオブジェクトとサイズをyieldで返す。
サイズを取得したいパスを与えると、中にあるパスの一覧とそれぞれのサイズを
yieldで返します。
"""
for path in Path(target_path).iterdir():
size = _get_size(path)
yield path, approximate_size(size)
if __name__ == '__main__':
for name, size in get_size():
print(name, size)
以下はDive Into PythonというPythonの入門サイト(のWeb版)にあった、ファイルサイズの変換処理です。
8277
のような数値を与えると、8.1 KiB
のような文字列に変換してくれます。
SUFFIXES = {
1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
}
def approximate_size(size, a_kilobyte_is_1024_bytes=True):
"""Convert a file size to human-readable form.
http://diveintopython3-ja.rdy.jp/your-first-python-program.html
Keyword arguments:
size -- file size in bytes
a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024
if False, use multiples of 1000
Returns: string
"""
if size < 0:
raise ValueError('number must be non-negative')
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000
for suffix in SUFFIXES[multiple]:
size /= multiple
if size < multiple:
return '{0:.1f} {1}'.format(size, suffix)
raise ValueError('number too large')
docstringの通りで、中にあるファイル・ディレクトリ一覧をiterdir()
で取得し、ファイルサイズを実際に取得する処理である_get_size()
に渡します。サイズを取得し終わったら、Pathオブジェクトと一緒に返却します。
def get_size(target_path='.'):
"""Pathオブジェクトとサイズをyieldで返す。
サイズを取得したいパスを与えると、中にあるパスの一覧とそれぞれのサイズを
yieldで返します。
"""
for path in Path(target_path).iterdir():
size = _get_size(path)
yield path, approximate_size(size)
if __name__ == '__main__':
for name, size in get_size():
print(name, size)
こちらが本命のファイルサイズ取得処理です。.stat().st_size
でファイルのサイズが取得できます。ディレクトリだった場合は中にあるファイルを合算する必要がありますので、iterdir()
を呼び出し各パスをまた_get_sizeに渡します。
def _get_size(path_obj):
"""そのパスのサイズを返す。
Pathオブジェクトを受け取ります。
ファイルだった場合はそのファイルサイズを、
ディレクトリだった場合は再帰的に取得したファイルサイズを返します。
"""
if path_obj.is_file():
return path_obj.stat().st_size
elif path_obj.is_dir():
return sum(_get_size(p) for p in path_obj.iterdir())