• Mémo Context manager maison : créer un environnement à la volée

  • Home made context manager: broadcast environment

Imaginons que l'on veuille faire des opérations à la volée sur des fichiers (ex: test). Imaginons qu'on veuille faire des opérations sur ces fichiers puis s'en débarasser. Pourquoi ne pas leur créer un petit environnement virtuel jetable ?

import os
import shutil
import functools

Le context manager sous forme d'objet. Il prend deux méthodes spéciales __enter__ et __exit__. folder() renvoie le chemin absolu du dossier créé. create_file(file) permet d'y créer un fichier.

class TestEnvironment:
    BASE_DIR = os.path.abspath(os.path.dirname(__file__))

    def __init__(self, dirname):
        self.dirname = dirname

    @property
    def folder(self):
        return os.path.join(self.BASE_DIR, self.dirname)

    def __enter__(self):
        print(f'''Initialize environment "{self.dirname}"''')
        try:
            os.mkdir(self.dirname)
        except FileExistsError:
            pass
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f'''Delete environment "{self.dirname}"''')
        shutil.rmtree(self.folder)

    def create_file(self, filename):
        return open(os.path.join(self.folder, filename), "w")

    def read_file(self, filename):
        return open(os.path.join(self.folder, filename), "r")

Et pour le fun un petit décorateur. ;)

def broadcast_env(name):

    def decorator(func):
        @functools.wraps(wrapped=func)
        def wrapper(*args, **kwargs):
            with TestEnvironment(name):
                try:
                    f = func(*args, **kwargs)
                except Exception as e:
                    print(f"ERROR :: {e}")
                    return False
            return f
        return wrapper
    return decorator

Exemple:

@broadcast_env("hotfix")
def truc(x):
    file = open("hotfix/test_file.txt", "w")
    file.write(f"Result: {x*x}")


truc(2)

Ou encore:

import json


with TestEnvironment("hotfix") as env:
    data = {
        "nom": "Dupont",
        "prénom": "Jean",
        "date_naissance": "12/12/2012"
    }

    with env.create_file("coucou.json") as file:
        json.dump(data, file, indent=2, ensure_ascii=True)

    assert os.path.exists("hotfix/coucou.json")

    with env.read_file("coucou.json") as file:
        output = json.load(file)
        print(output)

En sortie :

Initialize environment "hotfix"
{'nom': 'Dupont', 'prénom': 'Jean', 'date_naissance': '12/12/2012'}
Delete environment "hotfix"


22 novembre 2019 16:01