Python在从未调用issubclass()时抛出TypeError错误

9

我有一段代码,大部分时间都能完美运行,但偶尔会在回溯中出现以下错误:

File "/path/to/somefile.py", line 272, in somefile
    sm = -0.5 * (wv[0]**2. / sm2 + numpy.log(2. * numpy.pi * sm2))
TypeError: issubclass() arg 2 must be a class or tuple of classes

我知道issubclass()的作用并理解了错误,但我从未调用过它;代码中那一行纯属算术计算,所以我不知道为什么会首先引发这个TypeError。我的唯一理论是Numpy在幕后调用它,但是跟踪回溯应该显示Numpy源代码中有问题的行,对吗?到底发生了什么?
更新: wv是一个浮点数数组,而sm2是一个浮点数标量。实际上,这个错误是由numpy.log抛出的,也就是(新的)这一行。
tmp = numpy.log(2. * numpy.pi * sm2)

没有更多的错误信息提供。
更多更新:
我的当前版本的Numpy(来自Python提示):
>>> import numpy
>>> numpy.__version__
'1.6.2'

我将问题行更改为:
try:
    tmp = numpy.log(2. * numpy.pi * sm2)
except TypeError:
    print type(sm2), 2. * numpy.pi * sm2

并获得了输出结果

<type 'numpy.float64'> 0.0

因此,出现某种错误是有道理的,但如果我在Python提示符下执行以下操作:

>>> import numpy
>>> numpy.log(0.)

我得到了我所期望的错误(并且已经通过warning模块在相关代码中进行了处理):

__main__:1: RuntimeWarning: divide by zero encountered in log
-inf

2
你没有说明每个变量是什么,但是你可以将这个语句分成小段来查看错误发生的位置(可能在 numpy.log)。 - JBernardo
@PhilFrost,sm2的值为0。这就解释了为什么应该会出现某种错误,但我本来期望会有一个RuntimeWarning(请参见我的上面更新),而我已经在处理它了。 - emprice
@seberg,我的Numpy版本是1.6.2,type(sm2)给出的结果是<type 'numpy.float64'> - emprice
@nosuchthingasstars,请报告它作为一个bug,不报告它没有任何意义,最坏的情况是它会一直存在几个月... numpy已经在np.log中为0给出了-inf,并为负数给出了nan,所以你可以直接使用它们? - seberg
1
我会报告这个问题。另外,我刚刚发现了这个,以前从未想过去查找它。看起来Numpy有一种内部处理RuntimeWarning的方法,所以我会尝试使用它。感谢您在解决这个问题上的所有帮助! - emprice
显示剩余7条评论
1个回答

3
这其实是我的代码中的一个错误...正如@seberg所指出的那样,这段代码可以正常工作:
>>> import numpy
>>> import warnings
>>> numpy.log(0.)
__main__:1: RuntimeWarning: divide by zero encountered in log
-inf
>>> warnings.simplefilter("error", RuntimeWarning)    # not "RuntimeWarning"
>>> try:
...     numpy.log(0.)
... except RuntimeWarning:
...     print "caught"
...
caught

numpy.seterr提供了一种替代方式来处理RuntimeWarning,如下所示:

>>> import numpy
>>> numpy.seterr(all='raise')
{'over': 'warn', 'divide': 'warn', 'invalid': 'warn', 'under': 'ignore'}
>>> try:
...     numpy.log(0.)
... except FloatingPointError:
...     print "caught"
... 
caught

不管怎样,它都能工作,但是Python应该为将字符串而不是类传递给警告简单过滤器引发某种异常。

1
抱歉,是我的错...只需编辑您的答案,但当然必须是warnings.simplefilter("error", RuntimeWarning)。如果有什么问题,Python可能会在实际事件之前提前发出警告... - seberg
warnings.simplefilter 可能不会引发异常,因为 字符串可以作为有效的异常,至少在 Python 2.6 之前是如此。也许您正在使用旧版本,或者 warnings 模块没有收到备忘录。 - Phil Frost
@PhilFrost,这是Python 2.7.3版本,所以我想它必须是warnings - emprice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接