Solution pour le rendement de Python 2.4 pas autorisé dans le bloc d'essai avec finally
-
22-09-2019 - |
Question
Je suis coincé sur python2.4, donc je ne peux pas utiliser une clause finalement avec des générateurs ou yield
. Y at-il moyen de contourner cela?
Je ne peux pas trouver les mentions de la façon de contourner cette limitation en Python 2.4, et je ne suis pas un grand fan des solutions de contournement que j'ai pensé (impliquant principalement __del__
et essayer de faire en sorte qu'il fonctionne dans un délai raisonnable) ne sont pas très attrayante.
La solution
Vous pouvez dupliquer le code pour éviter le bloc finally:
try:
yield 42
finally:
do_something()
Devient:
try:
yield 42
except: # bare except, catches *anything*
do_something()
raise # re-raise same exception
do_something()
(je ne l'ai pas essayé cela sur Python 2.4, vous devrez peut-être regarder sys.exc_info au lieu de reraise énoncé ci-dessus, comme dans raise sys.exc_info[0], sys.exc_info[1], sys.exc_info[2]
.)
Autres conseils
Le seul code qui est garanti à appeler quand une instance de générateur est simplement abandonné (ramasse-miettes) sont les méthodes de __del__
pour ses variables locales (si aucune référence à ces objets existent en dehors) et les callbacks pour faibles références à ses variables locales (idem). Je recommande la route de référence faible, car il est non-invasive (vous n'avez pas besoin d'une classe spéciale avec un __del__
- juste tout ce qui est faiblement référençables). Par exemple:.
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
cela ne finis!
d'impression, comme vous le souhaitez.