連載
» 2019年11月05日 05時00分 公開

[Python入門]ファイル操作と例外処理Python入門(2/2 ページ)

[かわさきしんじ,Deep Insider編集部]
前のページへ 1|2       

ファイルをコピーする関数に例外処理を組み込む

 次にもう少し難しい例としてファイルをコピーする関数を考えてみよう。元のコードは以下の通りだ(もちろん、ファイルをコピーするだけなら、前回に見た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()

ファイルをコピーするfile_copy関数

 この関数はパラメーター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()

ファイルコピーに例外処理を組み込んだ例1

 これは最初の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引数に存在しないファイルを指定したときも同様だ。

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。