(j'en ai un qui me hante depuis 2 jours à propos des coroutines, et je pense que je vais finir par l'écrire sinon il va m'obséder)
Bon, j'ai pas pu m'empêcher, il a fallu que je prépare un programme d'exemple pour écrire cet article, voilà un petit pattern sympa qui utilise des coroutines : comment parser un fichier xml de façon incrémentale pour ne traiter que les données qui nous intéressent au moyen d'une machine à états implémentée avec des coroutines.
Ici, une machine à états générique, configurée pour récupérer les titres des derniers articles publiés sur Zeste De Savoir (qu'on peut imaginer compiler automatiquement en lui passant en argument le chemin "item/title") :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | #!/usr/bin/env python3
from xml.etree import cElementTree as ElementTree
from urllib.request import urlopen
STATES = {
'default_state': {
'transitions': {
'item': 'item_state',
},
},
'printer': {
'do_print': True
},
'item_state': {
'transitions': {
'title': 'printer',
},
},
}
def state(tag_name, transitions={}, do_print=False):
while True:
event, element = yield
tag = element.tag
if event == 'start' and tag in transitions:
state_name = transitions[tag]
state_args = STATES[state_name]
yield from state(tag, **state_args)
elif (event, tag) == ('end', tag_name):
if do_print:
print(element.text)
return
state_machine = state('root', **STATES['default_state'])
next(state_machine)
rss = urlopen('https://zestedesavoir.com/articles/flux/rss')
for data in ElementTree.iterparse(rss, ('start', 'end')):
state_machine.send(data)
|
Oui, sans commentaire c'est imbitable. Mais on peut imaginer ça comme un "grep" pour des xml : la donnée est parsée petit bout par petit bout, et on se déplace dans une state machine au fur et à mesure que le parseur produit des événements. Quand on tombe sur un noeud qui nous intéresse, on en affiche le contenu… On peut imaginer parser des xml gigantesques de cette façon sans jamais saturer la mémoire (et de façon performante !).