似乎有些scipy模块扰乱了我的警告过滤器。请考虑以下代码。我的理解是,它应该只抛出一个警告,因为";一次";提供给自定义Warning类的筛选器。但是,scipy导入之后的警告也会显示出来。这是python 3.7和scipy 1.6.3的版本。
import warnings
class W(DeprecationWarning): pass
warnings.simplefilter("once", W)
warnings.warn('warning!', W)
warnings.warn('warning!', W)
from scipy import interpolate
warnings.warn('warning!', W)
这似乎只有在我导入某些scipy模块时才会发生。一个通用的";导入scipy";不要这样做。
我已经将它缩小到scipy.special.sf_error.py
和scipy.sparse.__init__.py
中设置的过滤器。我不知道该代码会如何导致问题,但它确实会。当我对那些filtersout进行注释时,我的代码会按预期工作。
我是不是误解了什么?是否有不涉及重写warnings.filterwarnings
/warnings.simplefilters
的解决方案?
这是一个开放的Python错误:https://bugs.python.org/issue29672.
特别注意Tom Aldcroft评论的最后一部分:
即使是文档更新也会很有用。这不仅可以解释
catch_warnings()
,而且可以解释通常的意外功能,即如果堆栈中任何位置的任何包都设置了警告过滤器,则会全局重置以前是否看到过警告(通过对_filters_mutated()
的调用(。
scipy/special/sf_error.py
中的代码设置了一个警告过滤器,这将导致以前看到过的警告的全局重置。(如果您将warnings.warn('warning!', W)
的另一个调用添加到示例代码的末尾,您应该看到它不会引发警告。(