プログラムを中断せずにPythonで警告を発生させる


189

プログラムをクラッシュ/停止/中断させずに、Pythonで警告を発生させようとしています。

次の簡単な関数を使用して、ユーザーがゼロ以外の数値を渡したかどうかを確認します。その場合、プログラムは警告を発しますが、通常どおり続行します。これは、下記のコードのように動作するはずですが、このクラスを使用する必要がありWarning()Error()またはException()代わりに、手動で警告をプリントアウトします。

def is_zero(i):
   if i != 0:
     print "OK"
   else:
     print "WARNING: the input is 0!"
   return i

以下のコードを使用して関数に0を渡すと、プログラムがクラッシュし、値が返されません。代わりに、プログラムを正常に続行させ、関数に0を渡したことをユーザーに通知するだけです。

def is_zero(i):
   if i != 0:
     print "OK"
   else:
     raise Warning("the input is 0!")
   return i

unittestでテストして警告がスローされたことをテストできるようにしたい。メッセージを出力するだけでは、単体テストでassertRaisesを使用してテストすることはできません。


どの程度正確にユーザーに通知しますか?メールまたはSMSを使用しますか?それはフックアップすることができますが、具体的にする必要があります。
aaronasterling

2
どうしてprintメッセージだけじゃないの?
sje397

1
@ sje397重要なのは、警告がスローされたことをunittestでテストできるようにしたいということです。メッセージを出力するだけでは、unittestのassertRaisesでそれを行うことができません。
Tomas Novotny

回答:


157

raise警告ではなく、warningsモジュールを使用する必要があります。上げると、警告ではなくエラーが発生します。


1
どうもありがとうございました。そして、ユニットテストを使用して警告がスローされたことをどのようにテストしますか?assertRaises()はもう使えません。
Tomas Novotny

@Tomas Novotny stdoutとstderrをキャプチャして、警告によって発行された文字列が中にあることを確認できます。
ウィーティー

15
@Tomas:警告をテストしたいという話は聞いたことがありwarnings.catch_warningsませんが、これを行うためのコンテキストマネージャがあります。
SilentGhost

290
import warnings
warnings.warn("Warning...........Message")

Pythonのドキュメントをご覧ください:こちら


6
またwarnings.warn("blabla", DeprecationWarning)、発行されている警告の種類にクラスを追加するため
shadi '30 / 12/19

52

デフォルトでは、例外とは異なり、警告は中断されません。

の後import warnings警告を生成するときにWarningsクラスを指定できます。指定されていない場合はUserWarning、デフォルトで文字どおりになります。

>>> warnings.warn('This is a default warning.')
<string>:1: UserWarning: This is a default warning.

代わりに既存のクラスを単に使用するには、例えばDeprecationWarning

>>> warnings.warn('This is a particular warning.', DeprecationWarning)
<string>:1: DeprecationWarning: This is a particular warning.

カスタム警告クラスの作成は、カスタム例外クラスの作成と似ています。

>>> class MyCustomWarning(UserWarning):
...     pass
... 
... warnings.warn('This is my custom warning.', MyCustomWarning)

<string>:1: MyCustomWarning: This is my custom warning.

テストについては、assertWarnsまたはを検討してくださいassertWarnsRegex


代替として、特にスタンドアロンアプリケーションの場合は、loggingモジュールを検討してください。これは、レベルの持つメッセージをログに記録することができ、デバッグ情報警告エラーをレベル持つなどのログメッセージ、警告以上がstderrに出力デフォルトです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.