最后尝试收益 - 我们是否提出异常?

时间:2014-04-28 17:11:58

标签: python exception-handling yield finally

TL; DR

是否有可能在finally子句中找出​​是否存在未完成的未捕获异常?

背景

我想迭代项目来对它们进行一些相对昂贵的处理,这可能会破坏并引发异常。所以我想保存我的位置。 但是保存状态也相当昂贵 - 所以我宁愿不是每次都这样做,只是在我屈服于的代码中出现异常时。

我正在想象一些模糊的形状:

def get_things(my_iterator):
    for items in my_iterator:
        try:
            yield item
        finally:
            if something_went_wrong():  # magic oracle function for failure
                save_state(item)
        continue_normal_processing()

但我不知道这是否可能。值得注意的是,except Exception:不会引发任何事情,因为此异常不在此函数中。

2 个答案:

答案 0 :(得分:5)

...似乎我对except的行为完全错了。

def f():
    for i in range(10):
        try:
            yield i
        except Exception:
            print "Nope, this broke"
            raise


for x in f():
    print x
    if x == 2:
        raise IndexError

返回

0
1
2
Nope, this broke
Traceback (most recent call last):
...
IndexError

答案 1 :(得分:1)

这应该与您想要的类似:

class CatchingExceptionsIterator:
    def __init__(self, generator):
        self.generator = generator
        self.error = None
    def __enter__(self):
        return self
    def next(self):
        if self.error is None:
            return next(self.generator)
        else:
            error = self.error
            self.error = None
            return self.generator.throw(*error)
    __next__ = next
    def __exit__(self, ty, err, tb):
        if ty is not None:
            self.error = ty, err, tb
            return True
    def __iter__(self):
        return self


def f():
    for i in range(10):
        try:
            print("yield")
            yield i
            print("returnFomYield")
        except:
            import traceback
            traceback.print_exc()


c = CatchingExceptionsIterator(f())
for i in c:
    with c:
        print(i)
        if i == 5:
            nameerror

必须调整它以适合确切的用例 输出是:

yield
0
returnFomYield
yield
1
returnFomYield
yield
2
returnFomYield
yield
3
returnFomYield
yield
4
returnFomYield
yield
5
Traceback (most recent call last):
  File "withiteration.py", line 27, in f
    yield i
  File "withiteration.py", line 39, in <module>
    nameerror
NameError: name 'nameerror' is not defined
yield
6
returnFomYield
yield
7
returnFomYield
yield
8
returnFomYield
yield
9
returnFomYield

还将执行额外的finally子句。

  

是否有可能在finally子句中找出​​是否存在未完成的未捕获异常?

为什么呢?您可以使用except。更详细地解释一下。