Python 我怎样才能捕捉到这样的警告';这是个例外(不仅仅是测试)?
我必须用Python为我正在做的一个项目制作一个拉格朗日多项式。我在做重心式的,避免使用显式的for循环,而不是牛顿的分差式。我遇到的问题是,我需要捕获一个除法为零的除法,但是Python(或者可能是numpy)只是将其作为一个警告,而不是一个正常的异常 所以,我需要知道如何捕捉这个警告,就像它是一个例外一样。我在这个网站上发现的相关问题没有以我需要的方式得到回答。这是我的密码:Python 我怎样才能捕捉到这样的警告';这是个例外(不仅仅是测试)?,python,exception,numpy,warnings,divide-by-zero,Python,Exception,Numpy,Warnings,Divide By Zero,我必须用Python为我正在做的一个项目制作一个拉格朗日多项式。我在做重心式的,避免使用显式的for循环,而不是牛顿的分差式。我遇到的问题是,我需要捕获一个除法为零的除法,但是Python(或者可能是numpy)只是将其作为一个警告,而不是一个正常的异常 所以,我需要知道如何捕捉这个警告,就像它是一个例外一样。我在这个网站上发现的相关问题没有以我需要的方式得到回答。这是我的密码: import numpy as np import matplotlib.pyplot as plt import
import numpy as np
import matplotlib.pyplot as plt
import warnings
class Lagrange:
def __init__(self, xPts, yPts):
self.xPts = np.array(xPts)
self.yPts = np.array(yPts)
self.degree = len(xPts)-1
self.weights = np.array([np.product([x_j - x_i for x_j in xPts if x_j != x_i]) for x_i in xPts])
def __call__(self, x):
warnings.filterwarnings("error")
try:
bigNumerator = np.product(x - self.xPts)
numerators = np.array([bigNumerator/(x - x_j) for x_j in self.xPts])
return sum(numerators/self.weights*self.yPts)
except Exception, e: # Catch division by 0. Only possible in 'numerators' array
return yPts[np.where(xPts == x)[0][0]]
L = Lagrange([-1,0,1],[1,0,1]) # Creates quadratic poly L(x) = x^2
L(1) # This should catch an error, then return 1.
执行此代码时,我得到的输出是:
Warning: divide by zero encountered in int_scalars
这就是我想要抓住的警告。它应该出现在列表理解中。您的配置似乎正在使用打印选项: 这意味着您看到的警告不是真正的警告,而是打印到标准输出的一些字符(有关详细信息,请参阅文档)。如果你想抓住它,你可以:
numpy.seterr(all='raise')
。然而,这改变了所有操作的行为,因此这是一个相当大的行为变化numpy.seterr(all='warn')
,这将把打印的警告转换为真实的警告,您将能够使用上述解决方案来定位这种行为变化警告
模块控制如何处理警告:
>>> import warnings
>>>
>>> warnings.filterwarnings('error')
>>>
>>> try:
... warnings.warn(Warning())
... except Warning:
... print 'Warning was raised as an exception!'
...
Warning was raised as an exception!
请仔细阅读的文档,因为它只允许您过滤所需的警告,并且有其他选项。我也会考虑查看哪一个是上下文管理器,它自动重置原来的<代码>过滤警告< /代码>函数:
>>> import warnings
>>> with warnings.catch_warnings():
... warnings.filterwarnings('error')
... try:
... warnings.warn(Warning())
... except Warning: print 'Raised!'
...
Raised!
>>> try:
... warnings.warn(Warning())
... except Warning: print 'Not raised!'
...
__main__:2: Warning:
您的配置似乎正在使用
打印
选项:
这意味着您看到的警告不是真正的警告,而是打印到标准输出的一些字符(有关详细信息,请参阅文档)。如果你想抓住它,你可以:
numpy.seterr(all='raise')
。然而,这改变了所有操作的行为,因此这是一个相当大的行为变化numpy.seterr(all='warn')
,这将把打印的警告转换为真实的警告,您将能够使用上述解决方案来定位这种行为变化警告
模块控制如何处理警告:
>>> import warnings
>>>
>>> warnings.filterwarnings('error')
>>>
>>> try:
... warnings.warn(Warning())
... except Warning:
... print 'Warning was raised as an exception!'
...
Warning was raised as an exception!
请仔细阅读的文档,因为它只允许您过滤所需的警告,并且有其他选项。我也会考虑查看哪一个是上下文管理器,它自动重置原来的<代码>过滤警告< /代码>函数:
>>> import warnings
>>> with warnings.catch_warnings():
... warnings.filterwarnings('error')
... try:
... warnings.warn(Warning())
... except Warning: print 'Raised!'
...
Raised!
>>> try:
... warnings.warn(Warning())
... except Warning: print 'Not raised!'
...
__main__:2: Warning:
要对@Bakuriu的回答补充一点: 如果您已经知道警告可能发生在何处,那么使用上下文管理器通常更为简洁,而不是将相同类型的所有后续警告视为相同,而不管它们发生在代码中的何处:
import numpy as np
a = np.r_[1.]
with np.errstate(divide='raise'):
try:
a / 0 # this gets caught and handled as an exception
except FloatingPointError:
print('oh no!')
a / 0 # this prints a RuntimeWarning as usual
编辑: 在我最初的示例中,我使用了
a=np.r\u0]
,但很明显,numpy的行为发生了变化,在分子都为零的情况下,被零除的处理方式有所不同。例如,在numpy 1.16.4中:
all_zeros=np.array([0,0.])
非全零=np.数组([1,0.])
使用np.errstate(divide='raise'):
不是所有的零/0引发浮点错误
使用np.errstate(divide='raise'):
全零/0没有提出例外
使用np.errstate(invalid='raise'):
全零/0引发浮点错误
相应的警告消息也不同:1./0。
记录为RuntimeWarning:true\u divide中遇到的除零
,而0。/0.
记录为运行时警告:在true\u divide中遇到无效值
。我不知道为什么会做出这样的更改,但我怀疑这与0的结果有关0。
不能表示为数字(在本例中,numpy返回一个NaN),而1。/0.
和-1./0.
根据IEE 754标准分别返回+Inf和-Inf
如果您想捕获这两种类型的错误,您可以始终传递
np.errstate(divide='raise',invalid='raise')
,或者all='raise'
,如果您想在任何类型的浮点错误上引发异常。为@Bakuriu的答案添加一点内容:
如果您已经知道警告可能发生在何处,那么使用上下文管理器通常更为简洁,而不是将相同类型的所有后续警告视为相同,而不管它们发生在代码中的何处:
import numpy as np
a = np.r_[1.]
with np.errstate(divide='raise'):
try:
a / 0 # this gets caught and handled as an exception
except FloatingPointError:
print('oh no!')
a / 0 # this prints a RuntimeWarning as usual
编辑: 在我最初的示例中,我使用了
a=np.r\u0]
,但很明显,numpy的行为发生了变化,在分子都为零的情况下,被零除的处理方式有所不同。例如,在numpy 1.16.4中:
all_zeros=np.array([0,0.])
非全零=np.数组([1,0.])
使用np.errstate(divide='raise'):
不是所有的零/0引发浮点错误
使用np.errstate(divide='raise'):
全零/0没有提出例外
使用np.errstate(invalid='raise'):
全零/0引发浮点错误
相应的警告消息也不同:1./0。
记录为RuntimeWarning:true\u divide中遇到的除零
,而0。/0.
记录为运行时警告:在true\u divide中遇到无效值
。我不知道为什么会做出这样的更改,但我怀疑这与0的结果有关0。
不能表示为数字(在本例中,numpy返回一个NaN),而1。/0.
和-1./0.
re