如何完全重置警告
How to reset warnings completely
如何在不重新启动的情况下再次看到警告python。现在我只见过他们一次。
例如考虑这段代码:
import pandas as pd
pd.Series([1]) / 0
我明白了
RuntimeWarning: divide by zero encountered in true_divide
但是当我再次 运行 它时,它会静默执行。
如何在不重启的情况下再次看到警告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__
里面只存了第二个?第一个存储在哪里?
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")
此时每次尝试除以零时,都会显示
RuntimeWarning: divide by zero encountered in true_divide
解释:
我们正在设置几个警告过滤器。第一个 (np.seterr
) 告诉 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到"forget"之前看到的警告时,你可以使用resetwarnings
:
# warns every time, because the warnings registry has been reset
for i in range(10):
warnings.resetwarnings()
np.true_divide(1, 0)
请注意,这还会重置您所做的任何警告配置更改。这让我想到...
选项 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.
如何在不重新启动的情况下再次看到警告python。现在我只见过他们一次。
例如考虑这段代码:
import pandas as pd
pd.Series([1]) / 0
我明白了
RuntimeWarning: divide by zero encountered in true_divide
但是当我再次 运行 它时,它会静默执行。
如何在不重启的情况下再次看到警告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__
里面只存了第二个?第一个存储在哪里?
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")
此时每次尝试除以零时,都会显示
RuntimeWarning: divide by zero encountered in true_divide
解释:
我们正在设置几个警告过滤器。第一个 (np.seterr
) 告诉 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到"forget"之前看到的警告时,你可以使用resetwarnings
:
# warns every time, because the warnings registry has been reset
for i in range(10):
warnings.resetwarnings()
np.true_divide(1, 0)
请注意,这还会重置您所做的任何警告配置更改。这让我想到...
选项 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.