# Open new file to write
file = None
try:
file = open(filePath, 'w')
except IOError:
msg = ("Unable to create file on disk.")
file.close()
return
finally:
file.write("Hello World!")
file.close()
上記のコードは関数からリッピングされています。ユーザーのシステムの1つが次のエラーを報告しています:
file.write("Hello World!")
エラー:
AttributeError: 'NoneType' object has no attribute 'write'
質問は、pythonが特定のファイルを開くのに失敗した場合、「except」ブロックが実行されて戻る必要がありますが、特定のエラーをスローしている行に制御が移ります。ファイル」変数は「なし」です。
ポインタはありますか?
finally
ブロック内のファイルに書き込むべきではありません。そこで発生した例外はexcept
ブロックによってキャッチされないためです。
Tryブロックによって発生した例外がある場合、except
ブロックが実行されます。 finally
ブロックalwaysは、何でも起こります。
また、file
変数をnone
に初期化する必要はありません。
return
ブロックでexcept
を使用しても、finally
ブロックはスキップされません。その性質上、スキップすることはできません。そのため、「クリーンアップ」コードをそこに配置する(つまり、ファイルを閉じる)必要があります。
したがって、try:except:finallyを使用する場合は、次のようにする必要があります。
try:
f = open("file", "w")
try:
f.write('Hello World!')
finally:
f.close()
except IOError:
print 'oops!'
これを行うもっときれいな方法は、with
ステートメントを使用することです。
try:
with open("output", "w") as outfile:
outfile.write('Hello World')
except IOError:
print 'oops!'
ファイルが開かれていない場合、file = open(filePath, 'w')
行は失敗するため、file
には何も割り当てられません。
次に、except
句が実行されますが、ファイルには何もないため、file.close()
は失敗します。
例外が発生した場合でも、finally
句は常に実行されます。 file
はまだNoneなので、別の例外が発生します。
例外がなかった場合にのみ発生することに対して、else
の代わりにfinally
句が必要です。
try:
file = open(filePath, 'w')
except IOError:
msg = "Unable to create file on disk."
return
else:
file.write("Hello World!")
file.close()
なぜelse
ですか? Pythonドキュメント say:
Else節の使用は、try節にコードを追加するよりも優れています。try... exceptステートメントで保護されているコードによって発生した例外を誤ってキャッチすることを避けるためです。
つまり、これはIOError
またはwrite
呼び出しからclose
をキャッチしません。その理由は、「ディスク上にファイルを作成できません」という理由がなかったからです。これは、コードが準備されていない別のエラーだったでしょう。このようなエラーを処理しようとしないことをお勧めします。
を含むロジックは何ですか
file.write("Hello World!")
finally
句内?? try
句自体に配置する必要があると思います。
try:
file = open(filePath, 'w')
file.write("Hello World!")
except IOError:
print("Unable to create file on disk.")
finally:
file.close()
これが問題に対する最も直接的な解決策です。 finally
ブロックでfile_obj != None
をチェックするイディオムを使用します。
ところで、file
はPythonクラス名であるため、別の変数名を選択する必要があります。
file = None
try:
file = open(filePath, 'w')
except IOError:
msg = ("Unable to create file on disk.")
file.close()
return
finally:
if file != None:
file.write("Hello World!")
file.close()
(タイプがIOErrorであるため)実行しないことを除いて、file = Noneであるため、AttributeErrorタイプの別のエラーをスローする最後の部分です。
次のようなことができます:
try:
do_some_stuff()
finally:
cleanup_stuff()
例外が発生した場合でも、最終的には常に「end」で呼び出されます。これを使用して、開いているリソース(DB接続、ファイルなど)が閉じられていることを確認できます。
セマンティクスを誤解したと思います。
ロジックは「try」内にある必要があり、「except」ブロック内の例外を処理する必要があり、メソッドがどのように終了しても「finally」が実行されるため、それを使用してクリーンアップします。