2016-01-11 96 views
5

私は壊れたパイプエラーをキャッチするためにいくつかのコードを書こうとしています。コードはPython 2.xとPython 3.xで動くべきです。壊れたパイプは、現在の構文またBrokenPipeErrorPython 2とPython 3で壊れたパイプをキャッチ

BrokenPipeError: [Errno 32] Broken pipe 

ある - 壊れたパイプはこれはPython 3.xの中で変更されたsocket.error

socket.error: [Errno 32] Broken pipe 

で表されるPythonの2.xaで

例外処理が少し変更されました(https://stackoverflow.com/a/34463112/263589参照)ので、私がする必要があるのは次のようなものです:

try: 
    do_something() 
except BrokenPipeError as e: # implies Python 3.x 
    resolve_for_python2() 
except socket.error as e: 
    if sys.version_info[0] == 2: # this is necessary, as in Python >=3.3 
           # socket.error is an alias of OSError 
           # https://docs.python.org/3/library/socket.html#socket.error 
     resolve_for_python3() 
    else: 
     raise 

残りの問題が1つあります:Python 2.xではBrokenPipeErrorが存在しないため、例外がある場合はいつでもdo_something()にPython 2.xが別の例外をスローして、BrokenPipeErrorを知らないと不平を言います。 socket.errorはPython 3.xで廃止されているため、近い将来Python 3.xでも同様の問題が発生する可能性があります。

このコードをPython 2.xおよびPython 3.xで実行するにはどうすればよいですか?

+0

http://python-future.org/compatible_idioms.htmlを見ると、例外処理が示されています。 – MKesper

+1

http://newbebweb.blogspot.in/2012/02/python-head-ioerror-errno-32-broken.htmlこちらは –

+0

ありがとうございます!しかし、http://python-future.org/compatible_idioms.html#catching-exceptionsでは、Python 2またはPython 3には存在しないが他のバージョンでは必須の例外をキャッチする方法については説明していません。 – speendo

答えて

3

のようにそれを使用することができます壊れたパイプエラーの場合は、socket.errorをキャッチして、本当に壊れたパイプエラーかどうかを確認してください。

例外のerrno属性を使用すると、Python 2とPython 3の両方に存在します。つまり、Python 2と3の異なるロジックは必要ありません(私は意図が少し明確にこの方法):

import socket 
import errno 


try: 
    do_something() 
except socket.error as e: 
    if e.errno != errno.EPIPE: 
     # Not a broken pipe 
     raise 
    do_something_about_the_broken_pipe() 

あなたが壊れたパイプよりも気にしない場合は、thefourtheyeの答えは適切かつ慣用的で​​す。

+0

ありがとうございます! Python 3では 'socket.error'は廃止予定ですので、Python 3のインタープリタを更新すると、(近い)将来に別の問題が発生するかもしれません。 – speendo

+1

@speendo数多くの参照がありますPython標準ライブラリ自体の 'socket.error' *。これは廃止されましたが、確かに、それはなくなっていません。 'socket.error'を削除することは、Pythonのコア開発者が将来避けようとしていることを公に明言している、無意味な改変です。もしそれが(数十年のうちに)削除されてしまったら、そのエラーは特定して修正するのは簡単ではないでしょう。その時点では、もはやPython 2をサポートしていないでしょう。 –

+0

意味があります.... – speendo

1

あなたはBrokenPipeErrorを使用して試してみて、それがNameErrorをスローした場合、この

import socket 
try: 
    expected_error = BrokenPipeError 
except NameError: 
    expected_error = socket.error 

のように、socket.errorにフォールバックそしてあなたが気にすべてがある場合は、この

try: 
    1 == 2 
except expected_error as ex: 
    # Handle the actual exception here 
関連する問題