无法禁止在导入调用期间执行的警告

Cannot suppress warnings that are executed during an import call

提问人:Induane 提问时间:6/30/2021 最后编辑:Induane 更新时间:6/30/2021 访问量:664

问:

当警告作为导入的一部分发出时,我无法在 Python 中过滤警告。我已经用 Python3.8 测试了以下内容。

这工作原理:

文件A:

import warnings

def old_func():
    warnings.warn("This is an old function.")
    pass

文件B:

import warnings
from file_a import old_func

warnings.simplefilter("ignore")
old_func()

警告消息按预期被禁止显示。但是,如果我像这样更改文件 A:

import warnings

def old_func():
    warnings.warn("This is an old function.")
    pass

old_func()

它停止工作。我以为这是因为我在导入之前没有设置过滤器,所以我更改了文件 B,如下所示:

import warnings
warnings.simplefilter("ignore")
from file_a import old_func
old_func()

而且仍然没有骰子。无论我做什么,都会发出警告。我还尝试了 catch_warnings() 上下文管理器,如下所示:

import warnings
with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    from file_a import old_func
    old_func()

警告仍会发出。如果在导入过程中发出警告,则似乎无法忽略它。

我做过一些骇人听闻的事情,比如暂时将 stderr 和 stdout 临时制作为内存中类似文件的对象,这很有效,但很糟糕。我想找到一种方法,用合理的机器来做到这一点。

由于这是针对具有使用 setuptools 创建的入口点的命令行工具,因此将其打包为最终用户的解释器是相当痛苦的。

侧面更新:我已经确认这在 Python 3.6 上有效,但在 Python 3.8 上不起作用。

python-3.x 导入 警告 suppress-warnings

评论

0赞 DeadSec 6/30/2021
也许因为您正在尝试使用该功能但启动了 2 个警告实例,这意味着您实际上并没有更改第一个实例的设置,而只是针对第二个实例。要解决此问题,您可以在第一个文件中禁止显示它,或者只在运行禁止代码的第一个文件中导入一个函数。我不知道这是否有效,因为我没有测试,但如果它有效,请告诉我,这样我就可以写出一个正确的答案。simplefilter
0赞 Induane 6/30/2021
@DeadSec,由于在我的实际工作中使用中,“文件 B”是一个上游库,我不能简单地改变它的行为。不过,应该可以使用警告过滤器来抑制警告。经过进一步检查,我的代码似乎在 Python3.6 上运行良好,但在 3.8 上却不能。奇怪。

答:

1赞 Lenormju 6/30/2021 #1

感谢您提供最小的可重复示例!

我遵循你的例子,每次都运行它们。但我没有观察到和你一样的事情:

# file: a.py
import warnings

def old_func():
    warnings.warn("This is an old function.")
    pass

old_func()
# file: b.py
import warnings
warnings.simplefilter("ignore")
from a import old_func
old_func()

在 Windows CPython 上没有为我发出警告。你能再检查一次吗?3.6.8

我以为这是因为我在导入之前没有设置过滤器,所以我按如下方式更改了文件 B 在我看来很合理

A 文件的最新版本也可以工作(即不显示警告)

评论

0赞 Induane 6/30/2021
我不再有 Python 3.6(事实证明,我已经将 python3.6 符号链接到 python3.8 二进制文件,用于任何预期 3.6 在我的路径上),所以我自己从头开始重新编译了它。瞧......未发出警告。一旦我在 Python 3.8 上运行它 - 警告就不再被禁止。我猜这意味着这是 Python 本身的一个错误;在 3.6 和 3.8 之间引入了一些回归。我在 Python 问题跟踪器上找不到任何错误报告,但我想我的 search-foo 可能达不到要求。我想我可以尝试一分为二,直到找到有问题的提交。
0赞 Lenormju 7/1/2021
@user1411616 Ubuntu 上的 CPython 上没有警告。www.online-python.com 上的 CPython 上没有警告3.8.23.8.5
1赞 Induane 7/9/2021
很奇怪;我只需切换解释器即可轻松重现。我在 3.8.10 上 - 我将尝试编译 3.8.5,看看问题是否仍然出现在那里。感谢您的检查!