如何完全重置警告

2024-10-04 07:25:17 发布

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

如果不重新启动python,我怎么能再次看到警告呢。现在我只见过他们一次。在

以以下代码为例:

import pandas as pd  
pd.Series([1]) / 0

我明白了

^{pr2}$

但当我再次运行它时,它会无声地执行。在

如果不重新启动python,我如何才能再次看到警告?


我已经试过了

del __warningregistry__

但这没用。在

似乎只有一些类型的警告存储在那里。 例如,如果我这样做:

def f():   
    X = pd.DataFrame(dict(a=[1,2,3],b=[4,5,6]))
    Y = X.iloc[:2]
    Y['c'] = 8

那么这只会在第一次调用f()时发出警告。 但是,现在当if do del __warningregistry__时,我可以再次看到警告。在


第一次和第二次警告有什么区别?为什么只有第二个存储在这个__warningregistry__中?第一个放在哪里?在


Tags: 代码import警告类型dataframepandasdefas
2条回答

How can I see the warning again without restarting python?

只要在脚本开始时执行以下操作,就不需要重新启动。在

import pandas as pd
import numpy as np
import warnings
np.seterr(all='warn')
warnings.simplefilter("always")

在这一点上,每次你试图除以零,它将显示

^{pr2}$

说明:

我们正在设置一些警告过滤器。第一个(^{})告诉NumPy它应该如何处理警告。我已经将其设置为在all上显示警告,但是如果您只想看到被零除的警告,请将参数从all更改为divide。在

接下来,我们更改希望warnings模块始终显示警告的方式。我们通过设置warning filter来实现这一点。在

What is the difference between first and second warning? Why only the second one is stored in this __warningregistry__? Where is the first one stored?

报告此问题的bug report中对此进行了描述:

If you didn't raise the warning before using the simple filter, this would have worked. The undesired behavior is because of __warningsregistry__. It is set the first time the warning is emitted. When the second warning comes through, the filter isn't even looked at. I think the best way to fix this is to invalidate __warningsregistry__ when a filter is used. It would probably be best to store warnings data in a global then instead of on the module, so it is easy to invalidate.

顺便说一句,bug在3.4和3.5版本中已经被关闭。在

warnings是一个非常棒的标准库模块。你会喜欢了解它的:)

有点背景

warnings的默认行为是只在第一次出现时显示来自特定行的特定警告。例如,以下代码将导致向用户显示两个警告:

import numpy as np

# 10 warnings, but only the first copy will be shown
for i in range(10):
    np.true_divide(1, 0)

# This is on a separate line from the other "copies", so its warning will show
np.true_divide(1, 0)

你有几个选择来改变这种行为。在

选项1:重置警告注册表

当您希望python“忘记”以前看到的警告时,可以使用^{}

^{pr2}$

请注意,这也会重置您所做的任何警告配置更改。这让我想到。。。在

选项2:更改警告配置

warnings module documentation更详细地介绍了这一点,但是有一个简单的选择就是使用simplefilter来更改默认行为。在

import warnings
import numpy as np

# Show all warnings
warnings.simplefilter('always')
for i in range(10):
    # Now this will warn every loop
    np.true_divide(1, 0)

由于这是一个全局配置更改,它具有全局影响,您可能希望避免这些影响(应用程序中任何位置的所有警告都将每次显示)。一个不那么激烈的选择是使用上下文管理器:

with warnings.catch_warnings():
    warnings.simplefilter('always')
    for i in range(10):
        # This will warn every loop
        np.true_divide(1, 0)

# Back to normal behavior: only warn once
for i in range(10):
    np.true_divide(1, 0)

对于特定类型的警告,还可以使用更精细的选项来更改配置。为此,请查看docs。在

相关问题 更多 >