警告可以在不退回功能的情况下发出警告吗?

时间:2018-04-07 00:01:06

标签: python

在warn()调用之后仍然执行其余代码时,警告是否有被捕获的warnings.warn()函数?我遇到的问题是函数b将warnings.warn()如果发生了什么,然后我希望该函数的其余部分完成其工作并返回它实际执行的列表。如果发出警告,我想抓住它,通过电子邮件发送给某人,并在我从另一个模块调用该函数时继续,但这种情况不会发生。这是代码中的样子:

import warnings
def warn_function(arg_1):
    if arg_1 > 10:
        warnings.warn("Your argument was greater than 10.")
    return arg_1 - 5

with warnings.catch_warnings():
    warnings.filterwarnings("error")
    try:
        answer = warn_function(20)
    except Warning:
        print("A warning was thrown")
    finally:
        print(answer)

1 个答案:

答案 0 :(得分:1)

是的,警告可以在不退出功能的情况下发出警告。但是你尝试做事的方式并不奏效。

catch_warningsthe "error" action一起使用意味着您明确要求Python将每个警告作为例外提出。并且Python异常模型无法从抛出异常的位置恢复。

可以重新组织你的代码,以便在每次可能的警告之后提供明确的方法来“完成剩下的工作”,但对于非平凡的情况,你最终要做大量的工作,或者建立一个hacky继续传递机制。

处理用例的正确方法是logging.captureWarnings。这样,所有警告都会转到名为'py.warnings'的记录器,而不是通过正常的警告路径。然后,您可以配置一个日志处理程序,通过电子邮件将这些警告发送给某人,您就完成了。

当然,一旦你构建了这个,你可以使用完全相同的处理程序来获取从高严重性日志消息发送到其他记录器的电子邮件,或添加运行时配置,以便您可以调高电子邮件阈值没有部署服务器的全新版本,等等。

如果您尚未使用logging,则可能更容易手动挂钩警告。正如the warnings introduction所解释的那样:

  

通过调用可能被覆盖的showwarning()来完成警告消息的打印;此函数的默认实现通过调用formatwarning()来格式化消息,def showwarning(message, category, filename, lineno, file=None, line=None): fmsg = warning.formatwarning(message, category, filename, lineno, line) # send fmsg by email warning.showwarning = showwarning 也可供自定义实现使用。

是的,Python鼓励您对stdlib模块进行monkeypatch。执行此操作的代码如下所示:

{{1}}