J’adore les context managers Python


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.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.