Pythonでは、ディレクトリ内のファイルやフォルダをリストアップするために様々な方法が提供されています。その中でも、再帰的に全てのファイルやサブディレクトリを処理するためには、特にosモジュールを使うことが有効です。

os.walkを使ったディレクトリツリーの再帰的な表示

最も一般的な方法として、os.walkを使ってディレクトリツリー全体を探索する方法があります。以下のコード例は、指定されたディレクトリ以下にある全てのファイルとフォルダを再帰的に取得して一覧表示します。

import os
for dirname, dirnames, filenames in os.walk('.'):
    for subdirname in dirnames:
        print(os.path.join(dirname, subdirname))
    for filename in filenames:
        print(os.path.join(dirname, filename))

このスクリプトでは、まず最初にサブディレクトリのパスを出力し、その後、ファイル名のパスを表示します。また、os.walk()の強力な点は、dirnamesリストを編集することで、特定のディレクトリへの再帰を防ぐことができる点です。例えば、.gitディレクトリを無視する場合、以下のようにリストから削除することで対応できます。

if '.git' in dirnames:
    dirnames.remove('.git')

このテクニックを使うと、探索の対象から特定のディレクトリを除外することが可能です。

os.listdirを使った簡単なファイル一覧表示

ディレクトリ内のファイルやフォルダのみを取得したい場合は、os.listdirが便利です。os.listdirは指定されたディレクトリ内に存在する全てのファイルとフォルダのリストを返しますが、サブディレクトリ内の探索は行いません。

import os
print(os.listdir('.'))

この関数はシンプルで使いやすいですが、再帰的な探索が必要な場合にはos.walkのほうが適しています。

os.scandirを使ったパフォーマンスの向上

さらにパフォーマンスを向上させたい場合は、os.scandirを使用するのが良い選択です。os.scandiros.DirEntryオブジェクトを返し、ファイルやフォルダに関する属性情報(例えば、is_file()is_dir())をすばやく取得できます。これは、ファイル属性情報が必要な場合や、非常に多くのファイルを処理する際に有効です。

import os
with os.scandir('.') as entries:
    for entry in entries:
        if entry.is_file():
            print(f"File: {entry.name}")
        elif entry.is_dir():
            print(f"Directory: {entry.name}")

os.scandirはシステムコールを減らすことで、特に大規模なディレクトリツリーの探索において、os.listdiros.walkに比べて高速に動作します。

応用例 - pathlibを使ったモダンなアプローチ

Python 3では、pathlibモジュールを使用することで、より直感的で読みやすいコードを書くことができます。例えば、Pathオブジェクトを使って、特定の拡張子を持つファイルだけを取得する場合、以下のように記述できます。

from pathlib import Path
for path in Path('.').rglob('*.py'):
    print(path)

rglob()メソッドを使うことで、再帰的にディレクトリを探索し、指定されたパターン(この場合は.py拡張子)に一致するファイルを取得します。これにより、複雑なフィルタリングも簡単に実現可能です。

まとめ

Pythonでは、ディレクトリの内容をリストアップするために複数の方法が提供されています。単純なディレクトリ一覧を取得する場合はos.listdirが有効ですが、再帰的な処理が必要な場合はos.walkを、よりパフォーマンスを重視する場合はos.scandirpathlibの使用を検討すると良いでしょう。それぞれの関数の特徴を理解し、目的に合った最適な方法を選択することが大切です。