Soluzione per la resa python 2.4 di non ammessi in blocco try con clausola finally
-
22-09-2019 - |
Domanda
Sono bloccato sul python2.4, quindi non posso usare una clausola finally con i generatori o yield
. C'è un modo per ovviare a questo?
Non riesco a trovare alcuna menzione di come aggirare questa limitazione in Python 2.4, e io non sono un grande fan delle soluzioni che ho pensato di (coinvolgendo principalmente __del__
e cercando di assicurarsi che venga eseguito all'interno di un tempo ragionevole) non sono molto attraente.
Soluzione
È possibile duplicare il codice per evitare il blocco finally:
try:
yield 42
finally:
do_something()
diventa:
try:
yield 42
except: # bare except, catches *anything*
do_something()
raise # re-raise same exception
do_something()
(non ho provato questo su Python 2.4, potrebbe essere necessario esaminare sys.exc_info invece del re-raise dichiarazione di cui sopra, come in raise sys.exc_info[0], sys.exc_info[1], sys.exc_info[2]
.)
Altri suggerimenti
L'unico codice che è garantito per essere chiamato quando un'istanza generatore viene semplicemente abbandonata (garbage collection) sono i metodi __del__
per le sue variabili locali (se non esistono riferimenti a tali oggetti esterno) ed i richiami per riferimenti deboli alle sue variabili locali (idem). Vi consiglio il percorso riferimento debole perché è non invasiva (non è necessario un classe speciale con un __del__
- proprio tutto ciò che è debolmente referenziabile). Per esempio:.
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
questo non fa di stampa finis!
, se lo desideri.