【问题标题】:How to disable Python warnings?如何禁用 Python 警告?
【发布时间】:2013-01-05 23:05:21
【问题描述】:

我正在处理使用warnings 库引发大量(目前对我而言)无用警告的代码。阅读(/扫描)文档我只找到了to disable warnings for single functions的方法。但我不想更改这么多代码。

python -no-warning foo.py这样的标志吗?

你会推荐什么?

【问题讨论】:

  • @MartinSamson 我大体上同意,但在某些情况下可以忽略警告。我通过在 defusedxml 中使用有效的 Xpath 语法获得了其中的几个:FutureWarning: This search is broken in 1.3 and earlier, and will be fixed in a future version. If you rely on the current behaviour, change it to [this other thing]。我宁愿现在忽略警告并等待它被静默修复,也不愿编写不必要的丑陋代码来避免无害的警告。

标签: python suppress-warnings


【解决方案1】:

当一切都失败时,使用这个:https://github.com/polvoazul/shutup

pip install shutup

然后添加到代码的顶部:

import shutup; shutup.please()

免责声明:我是该存储库的所有者。我在第五次需要这个之后写了它,但找不到任何简单的东西。

【讨论】:

    【解决方案2】:

    不复杂,就用这两行

    import warnings
    warnings.filterwarnings('ignore')
    

    【讨论】:

      【解决方案3】:

      这里是-W option

      python -W ignore foo.py
      

      【讨论】:

      • 要仅忽略特定消息,您可以在参数中添加详细信息。 man python 详细描述了它,除了模块名称规范。我花了很多时间猜测它。最后我得到了这个命令python3 -W ignore::UserWarning:git.cmd:914 ./test.py警告/usr/local/lib/python3.4/dist-packages/git/cmd.py:914: UserWarning: Python 3.5 support is deprecated...
      • 如果使用 ipython 调用函数时有没有办法做到这一点?
      【解决方案4】:
      import sys
      if not sys.warnoptions:
          import warnings
          warnings.simplefilter("ignore")
      

      在处理文件或添加新功能以重新启用警告时将忽略更改为默认值。

      【讨论】:

        【解决方案5】:

        查看 Python 文档的 Temporarily Suppressing Warnings 部分:

        如果您使用的代码您知道会引发警告,例如不推荐使用的函数,但又不想看到警告,则可以使用 catch_warnings 上下文管理器抑制警告:

        import warnings
        
        def fxn():
            warnings.warn("deprecated", DeprecationWarning)
        
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            fxn()
        

        我不宽恕它,但您可以取消所有警告

        import warnings
        warnings.filterwarnings("ignore")
        

        例如:

        >>> import warnings
        >>> def f():
        ...     print('before')
        ...     warnings.warn('you are warned!')
        ...     print('after')
        ...
        >>> f()
        before
        <stdin>:3: UserWarning: you are warned!
        after
        >>> warnings.filterwarnings("ignore")
        >>> f()
        before
        after
        

        【讨论】:

        • @Framester - 是的,IMO 这是抑制特定警告的最干净的方法,警告通常存在,因为可能出现问题,因此通过命令行抑制所有警告可能不是最好的选择。
        • @Framester - 我也列出了另一个选项和一个例子......我不太喜欢它(因为我在之前的评论中给出了原因)但至少现在你有了工具.
        • 如果您只希望捕获来自特定类别的警告,您可以使用 category 参数传递它:warnings.filterwarnings("ignore", category=DeprecationWarning)
        • 在这种情况下这对我很有用,因为 html5lib 会吐出 lxml 警告,即使它没有解析 xml。谢谢
        • warnings.filterwarnings 函数还有一个有用的参数:module。它允许您忽略来自指定模块的警告。
        【解决方案6】:

        更多pythonic方式来忽略警告


        由于 'warning.filterwarnings()' 不会抑制所有警告,我建议您使用以下方法:

        import logging
            
        for name in logging.Logger.manager.loggerDict.keys():
            logging.getLogger(name).setLevel(logging.CRITICAL)
        
        #rest of the code starts here...
        

        或,

        如果您只想抑制 特定 组警告,则可以这样过滤:

        import logging
            
        for name in logging.Logger.manager.loggerDict.keys():
            if ('boto' in name) or ('urllib3' in name) or ('s3transfer' in name) or ('boto3' in name) or ('botocore' in name) or ('nose' in name):
                    logging.getLogger(name).setLevel(logging.CRITICAL)
        
        #rest of the code starts here...
        

        【讨论】:

        • 措辞令人困惑,但有2种“警告”,OP提到的一种不会放入logging,除非你打电话给logging.captureWarnings(True)。他们专门讨论的是输出到 STDERR 的 warnings 模块,而不是记录级别为 WARNING 的消息。
        【解决方案7】:

        我意识到这仅适用于特定情况,但在 numpy 上下文中我真的很喜欢使用 np.errstate

        np.sqrt(-1)
        
        __main__:1: RuntimeWarning: invalid value encountered in sqrt
        nan
        

        但是,使用np.errstate:

        with np.errstate(invalid='ignore'):
            np.sqrt(-1)
        
        nan
        

        最好的部分是您可以仅将其应用于非常特定的代码行。

        【讨论】:

          【解决方案8】:

          您还可以定义环境变量(2010 年的新功能 - 即 python 2.7)

          export PYTHONWARNINGS="ignore"
          

          像这样测试:默认

          $ export PYTHONWARNINGS="default"
          $ python
          >>> import warnings
          >>> warnings.warn('my warning')
          __main__:1: UserWarning: my warning
          >>>
          

          忽略警告

          $ export PYTHONWARNINGS="ignore"
          $ python
          >>> import warnings
          >>> warnings.warn('my warning')
          >>> 
          

          对于弃用警告,请查看how-to-ignore-deprecation-warnings-in-python

          复制到这里...

          来自warnings module的文档:

           #!/usr/bin/env python -W ignore::DeprecationWarning
          

          如果您使用的是 Windows:将 -W ignore::DeprecationWarning 作为参数传递给 Python。最好通过转换为 int 来解决问题。

          (请注意,在 Python 3.2 中,默认情况下会忽略弃用警告。)

          或者:

          import warnings
          
          with warnings.catch_warnings():
              warnings.filterwarnings("ignore", category=DeprecationWarning)
              import md5, sha
          
          yourcode()
          

          现在您仍然可以得到所有其他 DeprecationWarnings,但不是由以下原因引起的:

          import md5, sha
          

          【讨论】:

          • 这对于在执行测试时忽略警告特别有用。使用tox,将PYTHONWARNINGS=ignore 添加到setenv 可以减少输出的脏污。
          • 对 AWS CLI 也非常有用。
          • 但这并没有忽略弃用警告。请问如何包含那个?
          【解决方案9】:

          如果你知道你经常遇到的无用警告是什么,你可以通过消息进行过滤。

          import warnings
          
          #ignore by message
          warnings.filterwarnings("ignore", message="divide by zero encountered in divide")
          
          #part of the message is also okay
          warnings.filterwarnings("ignore", message="divide by zero encountered") 
          warnings.filterwarnings("ignore", message="invalid value encountered")
          

          【讨论】:

            【解决方案10】:

            如果你不想要复杂的东西,那么:

            import warnings
            warnings.filterwarnings("ignore", category=FutureWarning)
            

            【讨论】:

            • 并将事情恢复到默认行为:warnings.filterwarnings("default", category=FutureWarning)
            【解决方案11】:

            这是一个老问题,但PEP 565 中有一些更新的指导,如果你正在编写一个你应该使用的 python 应用程序,可以关闭所有警告:

            import sys
            import warnings
            
            if not sys.warnoptions:
                warnings.simplefilter("ignore")
            

            推荐这样做的原因是它默认关闭所有警告,但至关重要的是允许它们通过命令行上的python -WPYTHONWARNINGS 重新打开。

            【讨论】:

            • 这是完美的,因为它不会在以后的执行中禁用所有警告
            【解决方案12】:

            警告通过 stderr 输出,简单的解决方案是将“2> /dev/null”附加到 CLI。这对许多用户来说很有意义,例如那些使用 centos 6 的用户,他们被 python 2.6 依赖项(如 yum)困住,并且各种模块在其覆盖范围内被推到灭绝的边缘。

            对于涉及 SNI 等的密码学尤其如此。可以使用以下 proc 更新 2.6 以进行 HTTPS 处理: https://urllib3.readthedocs.io/en/latest/user-guide.html#ssl-py2

            警告仍然存在,但您想要的所有内容都已向后移植。尽管 stdout 内容本身不会改变,但 stderr 的重定向将为您提供干净的终端/shell 输出。

            回应 FriendFX。第一 (1) 句以通用解决方案直接回应问题。第二 (2) 句考虑了引用的锚点重新“禁用警告”,它是特定于 python 2.6 的,并指出 RHEL/centos 6 用户不能直接不使用 2.6。尽管没有引用具体的警告,但第二 (2) 段回答了我最常遇到的 2.6 问题,即密码学模块中的缺点以及如何“现代化”(即升级、反向移植、修复)python 的 HTTPS/TLS 性能.第三 (3) 段仅解释了使用重定向和升级模块/依赖项的结果。

            【讨论】:

            • 感谢您花时间回答。但请严格按照主题回答:您提到了很多与当前问题无关的事情,例如 CentOS、Python 2.6、密码学、urllib、反向移植。您可以编辑您的问题以删除这些位。如果您想了解更多来自 OP 的详细信息,请在问题下方留言。
            猜你喜欢
            • 1970-01-01
            • 2014-08-11
            • 2012-08-03
            • 2011-05-19
            • 2012-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多