使用finally子句的try块中不允许使用python 2.4的产生方法

时间:2010-02-26 03:46:00

标签: python yield python-2.4 try-finally

我被困在python2.4上,所以我不能在生成器或yield中使用finally子句。有什么方法可以解决这个问题吗?

我在python 2.4中找不到如何解决这个限制的任何提及,我不是我想到的解决方法的忠实粉丝(主要涉及__del__并试图确保它在合理的时间内运行)不是很吸引人。

2 个答案:

答案 0 :(得分:7)

您可以复制代码以避免finally块:

try:
  yield 42
finally:
  do_something()

变为:

try:
  yield 42
except:  # bare except, catches *anything*
  do_something()
  raise  # re-raise same exception
do_something()

(我没有在Python 2.4上尝试过这个,你可能需要查看sys.exc_info而不是上面的re-raise语句,就像在raise sys.exc_info[0], sys.exc_info[1], sys.exc_info[2]中一样。)

答案 1 :(得分:2)

当生成器实例被简单地放弃(垃圾收集)时,唯一保证被调用的代码是其局部变量的__del__方法(如果外部没有对这些对象的引用)和弱引用的回调到它的局部变量(同上)。我推荐弱参考路线,因为它是非侵入性的(你不需要一个带有__del__的特殊类 - 只是任何弱引用的类)。 E.g:

import weakref

def gen():
  x = set()
  def finis(*_):
    print 'finis!'
  y = weakref.ref(x, finis)
  for i in range(99):
    yield i

for i in gen():
  if i>5: break

这会根据需要打印finis!