web-dev-qa-db-ja.com

IOErrorとOSErrorの違いは?

関数がIOErrorを発生させるのかOSErrorを発生させるのか(あるいは両方を発生させるのか)については常に混乱しています。これらの例外タイプの背後にある原則は何ですか?それらの違いは何ですか?いつ発生しますか?

私は当初、OSErrorは許可の拒否などのためのものだと思っていましたが、許可なしでファイルを開くとIOErrorが発生します。

29
Niklas R

2つのタイプの違いはほとんどありません。実際、コアPython開発者でさえ、実際の違いがないことに同意し、Python 3のIOErrorを削除しました(現在はOSErrorのエイリアスです)。 PEP 3151-OSおよびIO例外階層の修正 を参照してください:

これらの違いのいくつかは実装の考慮事項で説明できますが、多くの場合、より高いレベルではあまり論理的ではありません。たとえば、OSErrorIOErrorを区切る線はぼやけていることがよくあります。以下を考慮してください。

>>> os.remove("fff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: 'fff'
>>> open("fff")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'fff'

はい、それはまったく同じエラーメッセージを持つ2つの異なる例外タイプです。

独自のコードの場合は、OSErrorをスローすることに固執します。既存の関数については、ドキュメントを確認してください(キャッチする必要があるものを詳述する必要があります)が、両方を安全にキャッチできます。

try:
    # ...
except (IOError, OSError):
    # handle error

PEPを再度引用する:

実際、OSErrorはキャッチされるべきですが、IOErrorはキャッチされない、またはその逆の状況を考えるのは困難です。

44
Martijn Pieters