【问题标题】:Print only the message on warnings仅打印有关警告的消息
【发布时间】:2010-02-02 20:08:10
【问题描述】:

我在验证器中发出大量警告,我想禁止 stdout 中的所有内容,但提供给 warnings.warn() 的消息除外。

也就是说,现在我看到了:

./file.py:123: UserWarning: My looong warning message
some Python code

我想看看这个:

My looong warning message

编辑 2: 覆盖 warnings.showwarning() 原来是有效的:

def _warning(
    message,
    category = UserWarning,
    filename = '',
    lineno = -1):
    print(message)
...
warnings.showwarning = _warning
warnings.warn('foo')

【问题讨论】:

    标签: python warnings


    【解决方案1】:

    总是有猴子补丁:

    import warnings
    
    def custom_formatwarning(msg, *args, **kwargs):
        # ignore everything except the message
        return str(msg) + '\n'
    
    warnings.formatwarning = custom_formatwarning
    warnings.warn("achtung")
    

    【讨论】:

    • 在 Python 3.6 上我得到 TypeError: custom_formatwarning() got an unexpected keyword argument 'line'。所以我将函数签名更改为:def custom_formatwarning(message, category, filename, lineno, line='')
    • 我在 Python 3.6 中遇到了“同样有一个意外的关键字参数 'line'”,但我只是将签名更改为 def custom_formatwarning(msg, *a, **b):,因此它也捕获了关键字 args。
    • 我知道这个线程很旧,但是,您也可以使用 lambda 而不是函数:warnings.formatwarning = lambda msg, *args, **kwargs: f'{msg}\n'
    • 这应该是公认的答案,而不是另一个
    • 如何获得DeprecationWarning 之类的警告类型?我试过category,但它什么都没有
    【解决方案2】:

    使用logging module 代替warnings

    【讨论】:

    • 这是我最初尝试使用warnings 的绝大多数情况下的结果。如果您正在为warnings 苦苦挣扎,您应该考虑使用此选项。说真的。
    • 选择警告而不是 logging.warn stackoverflow.com/a/14762106/5335565
    【解决方案3】:

    Monkeypatch warnings.showwarning() 使用您自己的自定义函数。

    【讨论】:

    • 您阅读了链接吗?我引用:“您可以通过分配给warnings.showwarning来用替代实现替换此功能。”。手册本身建议您对模块进行monkeypatch。
    • 别担心,这是完全正常的python程序,一点也不激烈。
    【解决方案4】:

    我正在做的就是省略只是源代码行。这基本上是文档所建议的,但是要弄清楚到底要改变什么有点困难。 (特别是,我尝试以各种方式将源代码行排除在 showwarnings 之外,但无法让它按照我想要的方式工作。)

    # Force warnings.warn() to omit the source code line in the message
    formatwarning_orig = warnings.formatwarning
    warnings.formatwarning = lambda message, category, filename, lineno, line=None: \
        formatwarning_orig(message, category, filename, lineno, line='')
    

    仅传递 line=None 会导致 Python 使用 filenamelineno 自动计算出 line 的值,但传递一个空字符串可以解决此问题。

    【讨论】:

    • 我知道这已经很老了,但我做过类似的事情,而且也很有效。但是,如果我在函数内执行此操作,则警告行为会在全局范围内发生变化。在调用该函数采用修改后的行为之后,每个警告都会出现。你知道限制其影响的方法吗?
    • 嗯,我只在全球范围内使用过这个。作为一种变通的解决方法,您可以定义一个在lambda 中使用的全局变量来决定line 的值是否被覆盖。 (那时,也许使用命名函数而不是lambda?)
    • 不幸的是,我在哪里做这些事情并不重要。我也尝试了原始定义保存和恢复,但还没有成功。
    • 没关系,这显然是一个已知问题bugs.python.org/issue18081#msg191342。确实很烦
    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 2012-04-03
    • 2012-02-06
    • 1970-01-01
    • 2013-12-02
    • 2015-06-21
    • 2019-08-07
    • 2022-01-26
    相关资源
    最近更新 更多