在不中断程序的情况下在Python中引发警告

Tom*_*tny 147 python error-handling warnings exception-handling

我正在处理如何在Python中引发警告而不必让程序崩溃/停止/中断的问题.

我使用以下简单函数,只检查用户是否传递了非零数字.如果用户传递零,程序应警告用户,但继续正常.它应该像下面的代码一样工作,但应该使用类Warning(),Error()或Exception()而不是手动打印警告.

def is_zero(i):
   if i != 0:
     print "OK"
   else:
     print "WARNING: the input is 0!"
   return i
Run Code Online (Sandbox Code Playgroud)

如果我使用下面的代码并将0传递给函数,程序将崩溃并且永远不会返回值.相反,我希望程序正常继续,只是通知用户他将0传递给该函数.

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

我希望能够测试是否已经通过unittest对其进行了测试.如果我只是打印出来的消息,我就无法在unittest中使用assertRaises来测试它.

nec*_*cer 238

import warnings
warnings.warn("Warning...........Message")
Run Code Online (Sandbox Code Playgroud)

请参阅python文档:here

  • 以及 `warnings.warn("blabla", DeprecationWarning)` 用于向发出的警告类型添加一个类 (17认同)

Sil*_*ost 127

你不应该raise警告,你应该使用warnings模块.通过提高它你会产生错误,而不是警告.

  • @Tomas:我从未听说过要测试警告的愿望,但是有一个[`warnings.catch_warnings`](http://docs.python.org/library/warnings.html#warnings.catch_warnings)上下文管理器让你这样做. (12认同)

Acu*_*nus 36

默认情况下,与异常不同,警告不会中断.

导入后import warnings,可以在生成警告时指定Warnings类.如果未指定,则UserWarning默认情况下是字面意思.

>>> warnings.warn('This is my lazy warning.')
<string>:1: UserWarning: This is my lazy warning.
Run Code Online (Sandbox Code Playgroud)

简单地使用预先存在的类,例如Warning:

>>> warnings.warn('This is my generic warning.', Warning)
<string>:1: Warning: This is my generic warning.
Run Code Online (Sandbox Code Playgroud)

创建自定义警告类与创建自定义异常类类似:

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

<string>:1: MyCustomWarning: This is my custom warning.
Run Code Online (Sandbox Code Playgroud)

为了测试,请考虑assertWarnsassertWarnsRegex.


作为替代方案,尤其是对于独立应用程序,请考虑该logging模块.它可以记录具有的电平的消息调试,信息,警告,错误,等日志具有的电平警告或更高是默认打印到stderr.


Mar*_*hke 8

只是一个小演示片段

我对如何使用有点困惑warnings.warn,所以我在这里提供一个简短的演示。warnings.warn请注意 print("code running after warning") 在/之后如何执行/不执行raise UserWarning。warnings.warn 仅打印一次警告消息。

>>> import warnings
>>> 
>>> warnings.warn("test warning"); print("code running after warning")
<stdin>:1: UserWarning: test warning
code running after warning
>>> 
>>> raise UserWarning('test warning'); print("code running after warning")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UserWarning: test warning
>>> 
>>> warnings.warn("test warning"); print("code running after warning")
code running after warning
Run Code Online (Sandbox Code Playgroud)

  • 他们是一样的。因此,区别在于,在第三种情况下,过去已经提出了警告 (3认同)