4

我被困在 python2.4 上,所以我不能将 finally 子句与生成器或yield. 有没有办法解决这个问题?

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

4

2 回答 2

7

You can duplicate code to avoid the finally block:

try:
  yield 42
finally:
  do_something()

Becomes:

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

(I've not tried this on Python 2.4, you may have to look at sys.exc_info instead of the re-raise statement above, as in raise sys.exc_info[0], sys.exc_info[1], sys.exc_info[2].)

于 2010-02-26T04:08:59.410 回答
2

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

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

这确实 print finis!,根据需要。

于 2010-02-26T06:27:09.943 回答