J'écris une petite bibliothèque qui tente de fournir une file d'attente permanente pour l'envoi de tâches. Mon code de persistance fournit un moyen d'itérer sur les descriptions de travail en attente; Je voudrais également garantir que les tâches envoyées finiront par être marquées comme terminées ou échouées.Utilisation conviviale d'un Python itérable sur une séquence de gestionnaires de contexte
Pour ce faire, je d'abord mis en oeuvre pour que mon utilisateur peut faire:
for c in some_iterator_object:
with c as x:
...
Je n'aime pas cette solution pour plusieurs raisons. Tout d'abord, je veux récupérer une description de travail de ma file en une seule opération (et échouer si la file est vide), donc l'acquisition est faite par la méthode __next__
de l'itérateur, et la sortie dans le __exit__
du contexte directeur.
Pour que le gestionnaire de contexte soit appelé, mon __next__
renvoie une classe wrapper qui ne peut pas être substituée directement à la valeur, de sorte qu'il génère une erreur manifeste si l'utilisateur oublie d'appeler le gestionnaire de contexte.
Existe-t-il un moyen de réduire ces deux instructions en une seule? Idéalement, je voudrais laisser l'utilisateur faire tout
for x in some_iterator_object:
...
tout en étant capable d'intercepter des exceptions soulevées par le contenu du bloc pour.
EDIT: J'ai découvert en expérimentant que si je laisse un générateur inachevé obtenir déchets collectés, la déclaration de rendement déclenche une exception interne, donc je peux écrire quelque chose brut comme
try:
...
success = False
yield val
success = True
...
finally:
if success:
...
Mais si je comprends bien , cela dépend du garbage collector pour fonctionner, et il semble être un mécanisme interne que je ne devrais pas vraiment toucher.
Merci, mais d'un point de vue de la convivialité, cela permet seulement à mon utilisateur d'échanger les instructions 'with 'et' for', donc ce n'est pas une grande amélioration de l'utilisabilité. J'accepte la réponse quand même, parce que je me suis rendu compte que je demandais l'impossible: je dois aussi être capable de piéger des exceptions spécifiques à l'intérieur du corps et de laisser la boucle continuer, et je le fais en insérant un boucle mais en dehors de la construction avec. Donc, je parierais qu'il n'y a aucun moyen de fusionner les deux constructions, sauf la réimpression desdites exceptions avec un type codé en dur. Je dois y penser plus. – b0fh