19

基本的な質問:独自のカスタム警告クラスを作成する最も Pythonic/論理的な方法は何ですか? サブクラス化する必要がある正しい警告クラスと例外クラスは何ですか?

動機: 私が書いているライブラリの要件では、MyContainerオブジェクトcにアイテムが含まれていてx、ライブラリの呼び出し元が の「複製」を配置しようとすると、xそれyc呼び出して、呼び出し元に警告が発行され、の戻り値は、置換するためにc.my_transformation_method(x, y)配置されます。言い換えると、s は要素をその複製に置き換えますが、そうするときはユーザーに警告する必要があります。cxMyContainer

私の読書に基づくと、致命的ではないアクションについてライブラリの呼び出し元に警告する最も柔軟な方法は、警告標準モジュールを使用することです。これにより、呼び出し元は、警告を無視することからエラーとして処理することまで、必要に応じて警告を処理できます。(私は Python 3 を使用していることに注意してください。ただし、ここでの質問にはそれが不可欠ではないと思います。)

例:私が行ったことは、次の警告サブクラスを定義することです:

class DuplicateItemWarning(UserWarning, ValueError):
    pass

次に、重複するアイテムを挿入しようとする試みを検出したときにadd()メソッドをMyContainer呼び出します。warnings.warn('detected duplicate', DuplicateItemWarning)

具体的な質問:

  1. 上記のようにサブクラス化する必要がありますかUserWarning、それとも単にサブクラス化する必要がありWarningますか?

  2. 呼び出し元が警告をエラーとして扱いたい場合に備えて、サブクラスValueError(上の例でValueErrorは、MRO の と の間にWarning挿入するだけ) は意味的に適切に見えます。Exception私が見ていないこれに欠点はありますか?

  3. 警告クラスのカスタマイズに関する StackOverflow に関する以前の質問は見つかりませんでした。warningsこれは、Python プログラマーがモジュールの使用を好まないからでしょうか?

4

1 に答える 1

6

警告フレームワークと警告ドキュメントに関するPEP230を読んだ後、私はあなたの質問に対する答えを持っていると思います

  1. UserWarning他のすべては警告カテゴリであり、分類以外の役割はないようです。このようにして、たとえば本番環境でそれらをフィルターで除外できます。したがって、基本的に、Warning警告が他のカテゴリに分類されない場合からサブクラス化できます。状況に応じてUserWarningまたはRuntimeWarning十分と思われる場合は、それらを使用してください。

  2. WarningsはすでにExceptionsです。したがって、技術的には、それらをエラーとして「キャッチ」するには、フィルターを変更するだけで、からサブクラス化する必要はありませんXXXError。さて、これもまた、理にかなっていることがすべてです。警告が渡された値に関するものである場合ValueError、特に多くの異なるカスタム警告がある場合は、呼び出し元が値に関するすべての警告を一度に「キャッチ」することを期待できます。

    try:
         # do something
    except MyCustomWarningOne:
        # do something else
    except MyCustomWarningTwo:
        # do something else also
    except ValueError: # or RuntimeWarning if you subclass from it
        # catch some other warning (both of these subclass from ValueError for example)
    
  3. warningsモジュールはGuidovanRossumのアイデアです。(PEP 230を参照)。それがPythonicではない場合...:D

于 2012-04-25T20:16:48.377 に答える