Обходной путь для выхода Python 2.4 не допускается в блоке try с условием finally - PullRequest
4 голосов
/ 26 февраля 2010

Я застрял на python2.4, поэтому я не могу использовать предложение finally с генераторами или yield. Есть ли способ обойти это?

Я не могу найти упоминаний о том, как обойти это ограничение в Python 2.4, и я не большой поклонник обходных путей, о которых я думал (в основном, включающих __del__ и пытающихся убедиться, что он работает в разумные сроки) не очень привлекательны.

Ответы [ 2 ]

7 голосов
/ 26 февраля 2010

Вы можете дублировать код, чтобы избежать блока 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 sys.exc_info[0], sys.exc_info[1], sys.exc_info[2].)

2 голосов
/ 26 февраля 2010

Единственный код, который гарантированно вызывается, когда экземпляр генератора просто отбрасывается (сборщик мусора), это методы __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!, по желанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...