[Python入門]ファイル操作と例外処理:Python入門(2/2 ページ)
ファイル操作には例外処理が付きものだ。その基本的な書き方と、with文を使った、よりシンプルな表記について見ていこう。
ファイルをコピーする関数に例外処理を組み込む
次にもう少し難しい例としてファイルをコピーする関数を考えてみよう。元のコードは以下の通りだ(もちろん、ファイルをコピーするだけなら、前回に見たshutil.copy関数などを使うのがよい。これはあくまでもサンプルだ)。
def file_copy(src, dst):
fsrc = open(src, 'rb')
fdst = open(dst, 'wb')
content = fsrc.read()
fdst.write(content)
fsrc.close()
fdst.close()
この関数はパラメーターsrcが指すコピー元ファイルを読み込みモードで開き(fsrcに代入)、パラメーターsrcが指すコピー先ファイルを書き込みモードで開いて(fdstに代入)、コピー元ファイルの内容を読み込んだ後に、それをコピー先のファイルに書き込み、最後に2つのファイルをクローズするという処理を行う。まだ、例外のことは考えていない。
実行例を以下に示す。
file_copy('foo.txt', 'bar.txt')
print(Path('bar.txt').read_text())
これを実行すると、次のようにコピーできていることが分かる。
このfile_copy関数に例外処理を組み込むとするとどうなるだろう。まずはtry文を素直に使ったコードを考えてみよう。例えば次のようなコードが考えられる。
def file_copy(src, dst):
try:
fsrc = open(src, 'rb')
fdst = open(dst, 'wb')
except OSError as e:
print(e)
else:
try:
content = fsrc.read()
fdst.write(content)
except Exception as e:
print(e)
finally:
fsrc.close()
fdst.close()
これは最初のtry節でコピー元とコピー先の2つのファイルをオープンして、それらをオープンできたら、else節の中で実際のコピー処理を行おうというものだ。そして、最後に大外のfinally節で2つのファイルをクローズする。
実際には、このコードはあまりよろしくない。最初のtry節で、どちらかのファイルをオープンできなかった場合に、finally節でオープンできなかったファイルまでクローズしようとしてしまうからだ(オープンできなかった時点で、そのopen関数呼び出しの結果が変数fsrc、fdstのいずれかに代入されないので、その名前は定義されないので、変数を参照しようとしたところで例外が発生する)。普通はしないことだが、以下のコードを実行してみると分かる。
file_copy('foo.txt', '') # コピー先のファイル名に空文字列を指定
このコードを実行すると、次のようになる。
「No such file or directory」というのは、except節で例外を処理したときに表示されたものだ。そして、その下でさらにUnboundLocalError例外が発生したことが分かる。変数fsrcにはオープンされたファイルを参照するオブジェクトが代入されたが、変数fdstには(ファイルがオープンされなかったので)何も代入されず、定義もされなかった。そのため、「fdstに代入される前に、その値が参照された」というメッセージが表示されたわけだ。これはfile_copy関数の第1引数に存在しないファイルを指定したときも同様だ。
Copyright© Digital Advantage Corp. All Rights Reserved.