如何在Python中确定地禁止使用DeprecationWarning?

2024-06-16 10:40:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我相信这个问题已经被提过很多次了,但是我有一个特定的用例,我不能用web上描述的许多方法来解决这个问题。在

在我的一个项目中,我使用了joblib库,它显示了DeprecationWarning,因为它在内部某处使用了imp库:

from sklearn.externals.joblib import Parallel, delayed

def main():
    xs = Parallel()(delayed(lambda x: x**2)(i) for i in range(1, 6))
    print(sum(xs))

if __name__ == '__main__':
    main()

我试图用解释器选项-W过滤掉警告,但没有帮助:

^{pr2}$

另外,我尝试使用warnings模块进行显式筛选,但也没有帮助:

import warnings
warnings.simplefilter('ignore', category=DeprecationWarning)
from sklearn.externals.joblib import Parallel, delayed

def main():
    xs = Parallel()(delayed(lambda x: x**2)(i) for i in range(1, 6))
    print(sum(xs))

if __name__ == '__main__':
    main()

我对matplotlib模块和其他一些第三方库也有类似的问题。可能还有其他一些方法(例如,环境变量),但我不明白为什么这些解决方案不起作用。在

有人能解释一下警告系统在Python中是如何工作的吗?第三方库是否有可能故意覆盖客户端的警告设置?我想说这个问题对我来说是最模糊的话题之一。在


Tags: 方法lambdafromimport警告parallelmaindef
2条回答

根据要求,以下是另一篇帖子的答案:

诀窍是在导入sklearn(或使用sklearn的依赖项,在我的例子中是hdbscan包)时使用“with”警告:

with warnings.catch_warnings():
    # filter sklearn\externals\joblib\parallel.py:268:
    # DeprecationWarning: check_pickle is deprecated
    warnings.simplefilter("ignore", category=DeprecationWarning)
    import hdbscan

这将仅对此模块禁用DeprecationWarning(因为warnings-modification附加到with块)。在

将此语句放在代码中导入模块的第一个位置非常重要,否则它将无法工作。E、 如果后面的cdg{I}已经加载了

因此,检查哪些模块/包使用joblib\parallel.py,以及从线性代码的角度来看,哪些模块/包最早加载到python对象堆中是非常重要的。在

[编辑]

正如@devforfu在评论中指出的,上面的解决方案不再有效。自从Python 3.7DeprecationWarning is once again shown by default when triggered directly by code in __main__.以来,我再次对此进行了研究。此外,ignore警告在依赖项显式加载其他包的折旧模块时似乎不起作用。在

这就是我的hdbscan示例中出现的情况,该示例加载折旧后的模块sklearn.external.six和{}。在

下面是如何最终解决这个恼人的问题:

  • 确保您已经显式安装了折旧的独立软件包,例如conda install -c conda-forge joblib six
  • 创建一个将覆盖依赖项导入的伪导入,例如:
^{pr2}$

如果没有导入错误,将使用独立的6和joblib。否则,例如,如果用户没有安装six或joblib,程序仍将工作(因为它从sklearn.externals公司),但会显示折旧警告。在

有趣的是,即使遵循@Alex的建议,我仍然有警告输出,如下所示:

import warnings
with warnings.catch_warnings():
    warnings.simplefilter('ignore', category=DeprecationWarning)
    from sklearn.externals.joblib import Parallel, delayed

def main():
    xs = Parallel()(delayed(lambda x: x**2)(i) for i in range(1, 6))
    print(sum(xs))

if __name__ == '__main__':
    main()

# $ python -W ignore example.py
# [...]
# DeprecationWarning: the imp module is deprecated in favour of importlib; 
# see the module's documentation for alternative uses
#  import imp
# 55

所以最终,我决定用一种非常老套的方式来做,并禁用所有的警告,因为我有点厌倦了寻找一种恰当的方法来处理它们。(不仅对于这个库,而且对于许多其他似乎非常渴望用不可抑制的警告轰炸您的库)。在

^{pr2}$

如果我错误地使用了@Alex的建议,或者你们中的一些人有更好的解决方案,我很乐意接受它作为答案。在


更新:

好吧,似乎很难影响在包中某个地方发出的警告。因此,最简单的事情可能是将warnings.warn替换为noop,或者以某种方式提前导入内部依赖项,并用上下文管理器抑制它们。在

相关问题 更多 >