【问题标题】:Workaround for python 2.4's yield not allowed in try block with finally clause使用 finally 子句的 try 块中不允许 python 2.4 的 yield 的解决方法
【发布时间】:2011-01-21 07:32:14
【问题描述】:

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

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

【问题讨论】:

  • 这么老的问题,虽然它适用于我目前的任务:«Python2.4.3 (#1, Oct 23 2012, (...) [GCC 4.1.2 20080704 »!

标签: python yield python-2.4 try-finally


【解决方案1】:

当一个生成器实例被简单地丢弃(垃圾收集)时,唯一保证调用的代码是其局部变量的 __del__ 方法(如果外部不存在对这些对象的引用)和对其弱引用的回调局部变量(同上)。我推荐弱引用路径,因为它是非侵入性的(你不需要带有__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

这会根据需要打印finis!

【讨论】:

    【解决方案2】:

    您可以复制代码以避免 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]。)

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-13
      • 2011-11-25
      • 2015-10-12
      相关资源
      最近更新 更多