2010-02-26 3 views
4

Я застрял на python2.4, поэтому я не могу использовать предложение finally с генераторами или yield. Есть ли способ обойти это?Обходной путь для выхода python 2.4 не разрешен в блоке try с окончательным предложением

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

ответ

6

Вы можете дублировать код, чтобы избежать, наконец, блок:

try: 
    yield 42 
finally: 
    do_something() 

Becomes:

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].)

2

Единственный код, который гарантированно вызывается, когда экземпляр генератора просто заброшен (мусор co lected) являются методами __del__ для его локальных переменных (если ссылки на эти объекты не существуют) и обратные вызовы для слабых ссылок на его локальные переменные (ditto). Я рекомендую слабый ссылочный маршрут, потому что он неинвазивный (вам не нужен специальный класс с __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!, как хотелось бы.