Question

Je fais quelque chose comme un planificateur de tâches en utilisant des générateurs comme coroutines. Dans le code ci-dessous, je dois exécuter le print cleanup de manière déterministe.

Il semble d'après mon interaction que la libération de l'objet au collecteur des ordures fait sortir le gestionnaire de contexte. Mais, je sais mieux que de compter sur le moment d'un GC. Est-ce vraiment le GC appelle le __exit__ Ou est-ce un autre mécanisme?

Comment puis-je strictement forcer print 'cleanup'?

>>> from contextlib import contextmanager
>>> @contextmanager
... def foo():
...     print 'setup'
...     try:
...         yield
...     finally:
...         print 'cleanup'
... 
>>> def bar():
...     with foo():
...         while True:
...             yield 'bar'
... 
>>> b = bar()
>>> b.next()
setup
'bar'
>>> b = None
cleanup
Était-ce utile?

La solution

Oui, le GC appelle le __del__ Cleanup Hook du générateur, qui à son tour soulève un GeneratorExit dans la fonction du générateur pour quitter le générateur (en appelant generator.close()).

Cela signifie le gestionnaire de contexte __exit__ Le crochet sera appelé chaque fois qu'une fonction de générateur est effacée de la mémoire.

Vous pouvez d'abord fermer le générateur manuellement, avec generator.close():

b.close()

Autres conseils

Vous devez faire sortir le générateur. Si la nature du générateur est de chercher pour toujours, vous pouvez utiliser gen.throw () pour lever une exception dans le générateur.

En fait, j'ai juste regardé la spécification des générateurs, et ils ont une méthode close () qui fait exactement cela (cela augmente une exception génératorexit () à l'intérieur du générateur. Alors appelez simplement gen.close () lorsque vous en avez fini avec tout Tous les gestionnaires de contexte invoqueront leur sortir Méthodes. Le générateur mangera l'exception afin que vous n'ayez pas besoin d'envelopper l'appel Close () dans un bloc d'essai:

>>> b= bar()
>>> b.next()
setup
'bar'
>>> b.close()
cleanup
>>>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top