Python 標準ライブラリには、開発者が問題を解決するために必要な機能のほとんどが含まれています。このチュートリアルでは、組み込みモジュールのみを使用してファイルまたはディレクトリの存在を確認するさまざまな方法を学びます。
ファイルまたはスクリプトが正しい場所にあるかどうかを確認することは、どの CLI プログラムにとっても重要です。実行時に特定のファイルが存在しない場合、プログラムは役に立たなくなる可能性があります。
今日のチュートリアルでは、Python でファイルまたはフォルダーが存在するかどうかを確認する簡単な方法をいくつか学びます。
始める前に
以下のコマンドを実行する前に、システムに Python 3 がインストールされていることを確認してください。ターミナルを開き、次のコマンドを入力します。
python --version
# Python 3.9.5, my result
2.x バージョンを入手した場合は、「python3」コマンドを使用する必要があります。 Python 3 がインストールされていない場合は、Python インストール ガイドを参照してください。
このチュートリアルではいくつかのテスト ファイルを使用するので、必ず次のファイルを作成してください。
touch testfile.txt
mkdir testdirectory/
touch testdirectory/otherfile.txt
上記のコマンドは、再生するファイル、testing ディレクトリ、および testingdirectory 内に別のファイルを作成します。ファイルの内容を読み取る必要がないため、ファイルは空であってもかまいません。
注: Windows を使用している場合は、グラフィカル ファイル マネージャーを使用してファイルの単純なファイル構造をセットアップします。
最後に、操作に優れたインターフェイスを提供する対話型 Python シェルとして Ipython を使用します。これは単なる商品なので、必ずしも必要というわけではありません。
pip install ipython
これを実行すると、 ipython と 入力するだけで美しい Python シェルにアクセスできるようになります。
これで準備は完了です。Python でフォルダーまたはファイルが存在するかどうかを確認する方法を見てみましょう。
試して、開いて、除外する
これが最も簡単なオプションです。存在しないファイルを開こうとすると、Python は FileNotFoundError を発生させます。
In [1]: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
これを利用して、探しているファイルが存在しない場合に例外を処理できます。
In [2]: try:
...: file = open('im-not-here.txt')
...: print(file) # File handler
...: file.close()
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\' exist')
...: exit()
...:
Sorry the file we're looking for doesn't exist
上記のコードでは、カスタム メッセージを出力し、ファイルが存在しない場合はプログラムの実行を停止しています。
exit() 関数は、例外が発生した場合にのみ実行されることに注意してください。探しているファイルが実際に存在する場合に何が起こるかを見てみましょう。
In [2]: try:
...: file = open('testfile.txt')
...: print(file) # File handler
...: file.close()
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\'t exist')
...: exit()
...:
<_io.TextIOWrapper name='testfile.txt' mode='r' encoding='UTF-8'>
ファイルを開いた直後にどのように閉じているかに注目してください。 Python のドキュメント によれば、これは良い習慣であると考えられています。
<span class="pre">file.write()</span>
<span class="pre">with</span>
>file.write()</span> を呼び出すか、<span class="pre">file.close()</span>
呼び出す<span class="pre">file.close()</span>
使用すると、プログラムが正常に終了した場合でも<span class="pre">file.write()</span>
の引数がディスクに完全に書き込まれない 可能性があります 。
ファイルに書き込んでいない場合でも、 複数のパフォーマンス上の問題が 発生する可能性があるため、ファイルを閉じることを強くお勧めします。
ファイルを自分で閉じたくない場合は、コンテキスト マネージャー を 使用してください。リソースの割り当てと解放が正確に行われるため、ファイルを閉じる必要はありません。
In [3]: try:
...: with open('testfile.txt') as file:
...: print(file)
...: # No need to close the file
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\'t exist')
...: exit()
...:
...:
<_io.TextIOWrapper name='testfile.txt' mode='r' encoding='UTF-8'>
この方法は、ファイルに書き込む場合には非常に便利ですが、ファイルが存在するかどうかだけを確認したい場合には非効率になります。これを達成するための他のオプションを見てみましょう。
os.path.exists()
os モジュールは、 オペレーティング システムと対話するための複数の機能を提供します。ファイルまたはフォルダーが存在するかどうかを確認するには、 パスを使用できます。 引数としてファイルまたはディレクトリへのパスを受け入れる exists() 関数。パスの存在に基づいてブール値を返します。
注: パスは、ファイルシステム内のファイルまたはディレクトリの一意の場所です。
Python では、 os.path サブモジュールには、ファイル パスを操作するために専用に設計された関数が含まれています。これらの関数はすべて、パス引数を文字列またはバイトとして受け入れ、絶対パスを使用するかどうかを決定できます。たとえば、次のようになります。
/home/daniel/.bashrc
または、スクリプトを実行しているディレクトリに応じて相対パスを使用します。
.bashrc
# Running the script in my home folder
以下は、テスト ファイルが置かれているディレクトリで実行されている os.path.exists() 関数を使用した複数の例です。
In [1]: import os
In [2]: os.path.exists('testfile.txt')
Out[2]: True
In [3]: os.path.exists('testdirectory')
Out[3]: True
In [4]: os.path.exists('hey-i-dont-exist')
Out[4]: False
ご覧のとおり、 testfile.txt ファイルと testdirectory フォルダーを使用してテストする場合は True を返し、ファイルが存在しない場合は False を 返します。
os.path.isfile()
(ディレクトリではなく) ファイルの存在のみを証明したい場合は、 os.path.isfile() 関数を呼び出します。
In [1]: import os
In [2]: os.path.isfile('testfile.txt')
Out[2]: True
In [3]: os.path.isfile('testdirectory/')
Out[3]: False
In [4]: os.path.isfile('i-dont-even-exist')
Out[4]: False
In [5]: os.path.isfile('testdirectory/otherfile.txt')
Out[5]: True
注: UNIX ではすべてのディレクトリがスラッシュ (/) で終わりますが、Windows ではバックスラッシュ (\) が使用されます。
上記のコードでは、 isfile() 関数が 2 回 False を返します。その理由を見てみましょう。
-
testdirectory/
はディレクトリであるため、ファイルとはみなされません。 Linux では すべてがファイル記述子である ため、これは絶対に正しいわけではありませんが、Python では便宜上ディレクトリを別の方法で扱います (ディレクトリを開こうとすると、 IsADirectoryError が発生します)。 -
i-dont-even-exist
皮肉にも存在しないファイルを指しています
os.path.isdir()
ディレクトリが正しい場所にあることを確認したい場合は、 os.path.isdir() 関数を使用する必要があります。この関数は、指定されたパスがディレクトリを指している場合にのみ True を返します。
In [1]: import os
In [2]: os.path.isdir('testfile.txt')
Out[2]: False
In [3]: os.path.isdir('testdirectory')
Out[3]: True
In [4]: os.path.isdir('anotherfile.txt')
Out[4]: False
パスが存在するファイルを指している場合でも、上記の例では False が 返されることに注意してください。
グロブ
glob モジュールは、 Unix シェルのようなパターン で動作する関数を提供します (したがって、Windows では適切に動作しません)。ファイルが現在のディレクトリ内のパターンと一致するかどうかを確認するには、 glob.glob() 関数を使用できます。
In [1]: import glob
In [2]: glob.glob('testfile.txt')
Out[2]: ['testfile.txt']
In [3]: glob.glob('testdirectory')
Out[3]: ['testdirectory']
上記のコードでは、glob 関数に渡されるパターンは、テスト ファイルとディレクトリへのパスを表す通常の文字列です。両方のパスが存在するため、関数はその中に一致するパス名を含むリストを返します。
注: パターンが一致しない場合は、空のリストが返されます。
パターンを glob 関数に渡すことができることを考えると、その主な利点のいくつかをテストしてみてはいかがでしょうか。
以下のコードは、それぞれ拡張子 .txt および .py を持つすべてのファイル パスを取得します。
In [4]: glob.glob('*.txt')
Out[4]: ['testfile.txt']
In [5]: glob.glob('*.py')
Out[5]:
['pathlib-exists.py',
'list-dir.py',
'glob-file.py',
'open-except.py',
'subprocess-test.py',
'isfile.py',
'exists.py',
'isdir.py']
パスクラスの使用
Path クラスは、 ファイル パスをオブジェクトとして操作するためのクリーンなインターフェイスを提供するため、パスを操作するための最良の方法の 1 つです。
さらに重要なのは、Path インスタンスには、特定のパスに関する情報を取得するために必要なメソッドがすべて備わっていることです。これには、前のオプションと同様の機能が含まれます。
注: pathlib ライブラリを使用するには、Python 3.4 以降が必要です。
使用する Path メソッドは次のとおりです。
パスが存在するかどうかを確認する
In [1]: from pathlib import Path
In [2]: Path('testfile.txt').exists()
Out[2]: True
In [3]: Path('im-not-here.txt').exists()
Out[3]: False
In [4]: Path('testdirectory').exists()
Out[4]: True
os.path.exists() と同じように機能します。
パスがファイルを指しているかどうかを確認する
In [5]: Path('testfile.txt').is_file()
Out[5]: True
In [6]: Path('testdirectory').is_file()
Out[6]: False
os.path.isfile() と同等。
パスがディレクトリを指しているかどうかを確認する
In [7]: Path('testfile.txt').is_dir()
Out[7]: False
In [8]: Path('testdirectory').is_dir()
Out[8]: True
os.path.isdir() に対応します。
サブプロセス
あなたがサブプロセスモジュールの愛好家であれば、このオプションについて知っておく必要があります。 test コマンド を使用すると、ファイルまたはフォルダーが存在するかどうかを確認できます。
注: test コマンドは Unix でのみ機能します。
次のテスト フラグによりジョブが完了します。
- test -e: パスが存在するかどうかを確認します
- テスト -f: ファイルが存在するかどうかを確認します
- test-d: フォルダーが存在するかどうかを確認します
さらにテスト フラグを詳しく知りたい場合は、次のコマンドを実行してマニュアルを読むことができます。
man test
サブプロセスを使用してパスを確認する:
以下のコードは、サブプロセスの戻りコードを 0 と比較することによって、パスが存在するかどうかを判断します。
Linux では、プロセスが正常に完了するとゼロが返され、失敗した場合は他のコードが返されることに注意してください。
In [1]: from subprocess import run
In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0
Out[2]: True
In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Out[3]: False
最初のステートメントでは、サブプロセス モジュールをインポートし、次に run 関数 を使用してその戻りコードを取得しています。
サブプロセスでファイルの存在を確認する
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0
Out[4]: True
In [5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out[5]: False
サブプロセスでディレクトリを確認します。
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0
Out[6]: False
In [7]: run(['test', '-d', 'testdirectory']).returncode == 0
Out[7]: True
このオプションの使用は、より多くのリソースを消費し、メリットも得られないため、あまり推奨されません。
総括する
Python は、OS と対話してプロセスを自動化するために最もよく使用されるプログラミング言語の 1 つです。これを使ってできる素晴らしいことの 1 つは、ファイルまたはフォルダーが存在するかどうかを確認することです。
最も簡単な方法は次のとおりです。
- ファイルを開いて例外をすぐに処理する
- os.path または pathlib モジュールの exists() 関数を使用します。
このチュートリアルでは次のことを学びました。
- ファイルを開いてファイルが存在しない場合に例外を処理する方法
- パスの意味
- os.path サブモジュールがファイルまたはフォルダーの存在を確認するために提供する 3 つの異なる関数
- Unix はスラッシュ (/) を使用しますが、Windows はバックスラッシュ (\) を使用します。
次に読む: Python のサブプロセスとは何ですか? 【5つの使用例】