En Python il y a plein de trucs pas du tout indispensables: les metaclasses, les décorateurs, les listes en intentions… Elles sont là uniquement pour rendre le langage plus agréable à l’usage, mais on pourrait faire sans. Les context managers en font partie. Loin de moi l’idée de faire un tuto ce matin sur les context managers, mais j’ai juste l’envie d’énoncer tout haut mon amour cette fonctionnalité.
Prenez un model Django Media: vous transcodez ce media, vous faites souvent des opérations dans son dossier. Il faut s’assurer que ça marche. Et quand ça foire, il faut s’assurer que l’on a bien nettoyé le répertoire de travail.
Hop:
class Media(models.Model): [...] @contextmanager def in_dir(self, delete_on_error=False): # si vous ne comprenez pas ce code, ne vous en faites pas, # c'est du Python avancé try: os.makedirs(self.dir) except (OSError, IOError) as e: pass try: yield self.dir except: if delete_on_error: shutil.rmtree(self.dir) raise |
Et voilà, Max dans ses scripts de transcoding magiques n’a pas à se poser de question. Il a juste à faire:
with media.in_dir(delete_on_error=True) as d: # faire des trucs avec le dossier dont le chemin est dans "d" |
Le chemin spécifique pour ce média est garanti d’exister.
Si il y a une exception, le dossier est garanti d’être nettoyé.
C’est simple, c’est propre, c’est beau. J’aime.