为什么异常可迭代?

时间:2008-11-03 09:46:03

标签: python exception

我最近被一些意想不到的东西咬了。我想做出类似的东西:

try :
     thing.merge(iterable) # this is an iterable so I add it to the list
except TypeError :
     thing.append(iterable) # this is not iterable, so I add it

嗯,它工作正常,直到我传递了一个继承自Exception的对象,该对象应该被添加。

不幸的是,异常是可迭代的。以下代码不会引发任何TypeError

for x in Exception() :
    print 1

有人知道为什么吗?

3 个答案:

答案 0 :(得分:11)

请注意,正在发生的事情与任何类型的隐式字符串转换等无关,但是因为Exception类实现了__getitem __(),并使用它来返回args元组中的值(ex.args)。您可以通过以下事实看到这一点:您将整个字符串作为迭代中的第一个也是唯一一个项目,而不是迭代字符串时您将获得的逐个字符结果。

这也令我感到惊讶,但考虑到这一点,我猜它是出于向后兼容的原因。 Python曾经(pre-1.5)缺少当前的异常类层次结构。相反,抛出字符串,(通常)一个元组参数,用于应该传递给处理块的任何细节。即:

try:
    raise "something failed", (42, "some other details")
except "something failed", args:
    errCode, msg = args
    print "something failed.  error code %d: %s" % (errCode, msg)

看起来这种行为是为了避免破坏1.5之前的代码,期望一个参数元组,而不是一个不可迭代的异常对象。在上面的link

的致命破损部分中,有几个这样的例子与IOError有关

字符串异常已经被推迟了一段时间,并且在Python 3中消失了。我现在已经检查了Python 3如何处理异常对象,看起来它们不再可以在那里迭代:

>>> list(Exception("test"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Exception' object is not iterable

[编辑]检查python3的行为

答案 1 :(得分:3)

无效。检查Brian anwser。

好的,我刚拿到它:

for x in Exception("test") :
    print x
   ....:     
   ....:     
test

不要打扰; - )

无论如何,很高兴知道。

编辑:看看评论,我想补充一些解释。

异常包含在实例化期间传递给的消息:

raise Exception("test") 

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: test

公平地说,消息是最好的定义Exception,所以str()返回它:

print Exception("test") 
test

现在,当Exceptions用于除Exception上下文以外的其他内容时,会发生异常被隐式转换为字符串。

所以当我这样做时:

for x in Exception("test") :
    print x

我正在迭代字符串“test”。

当我这样做时:

for x in Exception() :
    print x

我迭代一个空字符串。棘手。因为谈到我的问题:

try :
    thing.merge(ExceptionLikeObject)
except TypeError :
    ...

由于ExceptionLikeObject被视为字符串,因此不会引发任何内容。

现在,我们知道如何,但我仍然不是为什么。也许内置的Exception继承自内置的String?因为据我所知:

  • 添加 str 不会使任何对象可迭代。
  • 我通过重写 iter 绕过了问题,使其引发了TypeError!

不再是问题,但仍然是一个谜。

答案 2 :(得分:2)

实际上,我还是不太明白。我可以看到,迭代一个Exception会给你异常的原始args,我只是不确定为什么有人会想要这个。隐式迭代是我认为Python中为数不多的陷阱之一仍然让我兴奋不已。