''' @author: olivier.massot, févr. 2018 ''' import logging logger = logging.getLogger("model") class Model(): _mapping = {} @property def _fields(self): return list(self.__dict__.keys()) @property def data(self): return self.__dict__ def __repr__(self): return "<{} => {}>".format(self.__class__.__name__, ",".join(["{}={}".format(field, value) for field, value in self.__dict__.items()])) @classmethod def from_dict(cls, data): """ Retourne un objet à partir d'un dictionnaire de données """ model = cls() for key, value in data.items(): setattr(model, key, value) return model @classmethod def _map_type(cls, field, value): try: return cls._mapping[field](value) except KeyError: return value # Fonctions CSV def dump_to_csv(self, path): """ Ajoute les données du modèle au format CSV dans le fichier spécifié en paramètre. Créé le fichier s'il n'existe pas, avec une ligne d'en-tête """ if not path.exists(): logger.debug("Génère le fichier %s", path) firstline = "\t".join(self._fields + ["\n"]) with open(path, 'w+') as f: f.write(firstline) with open(path, 'a') as f: f.write("\t".join([str(getattr(self, field)).replace("\t", " ") for field in self._fields] + ["\n"])) @classmethod def load_csv(cls, path): """ parcourt les lignes du fichier csv et renvoie chaque ligne sous forme d'un objet Model ATTENTION: chaque propriété dont le type n'est pas précisé dans _mapping aura le type 'string' """ with open(path) as f: fields = next(f).split("\t") for line in f: data = {key: cls._map_type(key, value) for key, value in zip(fields, line.split("\t"))} yield(cls.from_dict(data))