4

実際のエラーに関するより良い情報をユーザーに提供するために、例外を再発生させようとしています。Python 3.3 にはPEP 409が含まれています。raise NewException from None元の例外のコンテキストを抑制する構文を追加します。

ただし、Python 3.2 をターゲットにしています。Python スクリプトは解析しますが、実行時にfrom None構文に遭遇すると生成さ れTypeError: exception causes must derive from BaseExceptionます。例えば:

try:
    regex_c = re.compile('^{}$'.format(regex)) 
except re.error as e:
    e_msg = 'Regular expression error in "{}"'.format(regex)
    e_reraise = Exception(e_msg)
    # Makes use of the new Python 3.3 exception syntax [from None]
    # to suppress the context of the original exception
    # Causes an additional TypeError exception in Python 3.2
    raise e_reraise from None

にカプセル化raise e_reraise from Noneするとtry、さらに大きな例外スタックトレースが生成されます。python3.3私のXubuntu 12.10は/usr/lib/python3/dist-packages/*、python3.2モジュール用にセットアップされたモジュールをプルするため、バージョンチェックも機能しません。(大規模なトレースバックError in sys.excepthook:を作成する便利なものを取得します。)

Python 3.3 で実行しているときに PEP 409 機能を使用し、Python 3.2 では黙って無視する方法はありますか?

4

2 に答える 2

5

exc.__cause__ = NonePython 3.3 でコンテキストの印刷を抑制するように設定できます。

except re.error as e:
    e_msg = 'Regular expression error in "{}"'.format(regex)
    e_reraise = Exception(e_msg)
    e_reraise.__cause__ = None  # 'raise e_reraise from None'
    raise e_reraise    

Python 3.3 では、raise exc from cause実際に使用すると次のようになります。

exc.__cause__ = cause
raise exc

と設定exc.__cause__すると、暗黙的に が設定されますexc.__suppress_context__ = True。がどのように処理されるかについては、 PEP 415を参照してくださいraise exc from None

exc.__cause__ = NonePython 3.2 で設定すると、何も変わりません。

$ python3.2
Python 3.2.3 (default, Apr 13 2012, 13:31:19) 
[GCC 4.2.1 Compatible Apple Clang 3.0 (tags/Apple/clang-211.12)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise ValueError()
... except:
...     exc = TypeError()
...     exc.__cause__ = None
...     raise exc
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
TypeError

しかし、Python 3.3 では、代わりにコンテキストが抑制されます。

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 08:16:08) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise ValueError()
... except:
...     exc = TypeError()
...     exc.__cause__ = None
...     raise exc
... 
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
TypeError

を使用したかのようにraise exc from None:

>>> try:
...     raise ValueError()
... except:
...     raise TypeError() from None
... 
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
TypeError
于 2013-02-27T22:14:55.463 に答える
3

リンクした PEP が解決策を提供します。

  • raise NewException() from None

元の例外を明示的に宣言する既存の構文に従います

  • exc = NewException(); exc.__context__ = None; raise exc

前の方法の非常に冗長な方法

したがって、新しい構文を避けて、冗長な同等のものを使用する必要があります。

割り当てを見たくない場合は、コードを関数に入れることができます。

def suppress_context(exc):
    exc.__context__ = None
    return exc

そして、次のようにします。

raise suppress_context(TheErrorClass())

編集: Martijn PEP 415が指摘したように、この動作が変更されました:

要約すると、raise exc from cause次と同等になります。

exc.__cause__ = cause
raise exc

したがって、に設定する代わりに、に設定__context__するNone必要があり__cause__ますNone

本当に新しい構文を使用したい場合、これを行う唯一の方法sys.excepthookは、トレースバック出力を解析して不要な部分を削除するものに置き換えることです。ただし、この場合、次のことも行う必要があります。

try:
    raise error from None
except TypeError:
    raise error

次に、excepthookトレースバックを検索し、行に関連する部分を削除する必要がある場合raise error from None。単純な作業ではなく、他のソリューションよりも多くのコードが必要になります。

于 2013-02-27T22:17:10.347 に答える