为什么异常可以迭代? [英] Why are Exceptions iterable?

查看:120
本文介绍了为什么异常可以迭代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近被一些意想不到的东西咬伤了。我想要这样做:

  try:
thing.merge(iterable)#这是一个可迭代的我添加到列表
除了TypeError:
thing.append(iterable)#这不是可迭代的,所以我添加

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



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

  ():
打印1

有人知道为什么吗?

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



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

  try:
raisesomething failed,(42,some other details)
除了某些失败,args:
errCode,msg = args
printsomething failed。错误代码%d:%s%(errCode,msg)

看起来这个行为是为了避免破坏pre-1.5代码,期望一个元组元素,而不是一个非迭代的异常对象。上述链接的致命破坏部分中有一些IOError的例子, a>



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

 >>>列表(异常(test))
追溯(最近的最后一次调用):
文件< stdin>,第1行,< module>
TypeError:'异常'对象不可迭代

检查python3的行为


I have been bitten by something unexpected recently. I wanted to make something like that:

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

Well, It was working fine until I passed an object inheriting from Exception which was supposed to be added.

Unfortunetly, an Exception is iterable. The following code does not raise any TypeError:

for x in Exception() :
    print 1

Does anybody know why?

解决方案

Note that what is happening is not related to any kind of implicit string conversion etc, but because the Exception class implements __getitem__(), and uses it to return the values in the args tuple (ex.args). You can see this by the fact that you get the whole string as your first and only item in the iteration, rather than the character-by-character result you'd get if you iterate over the string.

This surprised me too, but thinking about it, I'm guessing it is for backwards compatability reasons. Python used to (pre-1.5) lack the current class hierarchy of exceptions. Instead, strings were thrown, with (usually) a tuple argument for any details that should be passed to the handling block. ie:

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

It looks like this behavior was put in to avoid breaking pre-1.5 code expecting a tuple of arguments, rather than a non-iterable exception object. There are a couple of examples of this with IOError in the Fatal Breakage section of the above link

String exceptions have been depecated for a while, and are going away in Python 3. I've now checked how Python 3 handles exception objects, and it looks like they are no longer iterable there:

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

[Edit] Checked python3's behaviour

这篇关于为什么异常可以迭代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆