Création de classes

Le module cls permet de faciliter la création de classes présentant des propriétés génériques au sein du projet. Il s'agit le plus souvent de décorateurs rajoutant automatiquement un ensemble de fonctions à une classe au moment de sa définition.

Fonctions disponibles

Le décorateur cached est une version améliorée du décorateur property pour définir une propriété « intelligente » d'un objet. La valeur récupérée lors de chaque appel à la fonction sera, avant d'être renvoyée, mise en cache pour être repassée ensuite lors des appels suivants. De cette manière, l'objet peut être réutilisé à l'identique tant qu'il n'a pas besoin d'être changé.

Le décorateur extend prend une classe en paramètre. La fonction qu'il décore sera alors rajoutée comme une nouvelle méthode de cette classe. On peut en profiter pour spécifier d'autres décorateurs à appliquer automatiquement, tels que property, classmethod, staticmethod, etc. Un nom peut également être fourni si celui de la fonction ne convient pas tel quel.

Le décorateur singleton est à placer sur une classe. Il l'instancie alors et renvoie l'instance, en modifiant au passage la méthode __new__ pour qu'elle renvoie toujours la même instance. De cette manière, on utilise directement l'objet, unique, dont on vient de définir la classe.

Le décorateur nospare permet de mémoriser les instances crées et de les renvoyer. La construction de la classe doit prendre un paramètre qui servira à identifier l'objet (une chaîne de caractère, par exemple) : si une instance a déjà été créée pour ce paramètre, elle sera renvoyée au lieu d'en créer une nouvelle (cette méthode est notamment utilisée pour les trucs et leurs contrôles).

Le décorateur frozen ajoute à la classe sur laquelle on l'utilise des méthodes __setattr__ et __delattr__ pour empêcher de modifier ses attributs une fois qu'une valeur leur a été donnée (si la classe ne possède pas d'attribut __slots__, il restera possible d'ajouter des attributs arbitraires). Il reste possible de modifier/supprimer les propriétés « intelligentes » définies avec property si les méthodes dédiées ont été fournies (et il reste toujours possible d'utiliser object.__setattr__, mais il y a moins de chances de le faire par inadvertance).

La fonction associative (c'est la seule de ce module à ne pas être un décorateur) crée et renvoie une version améliorée des collections.namedtuple, qui peut ensuite être utilisée comme classe de base pour en redéfinir une autre. Par rapport à la classe de base, elle ajoute la possibilité de définir des alias, de fonctionner comme un dictionnaire, et d'utiliser la récupération « intelligente » des clefs décrite ci-dessous.

Le décorateur automap ajoute à une classe des méthodes values et iter automatiques pour fonctionner avec les __getitem__ et keys définies dans la classe sur laquelle on l'appelle. Ces méthodes fonctionneront comme des générateurs.

TODO Comme pour mapping ci-dessous, je pourrais sans doute rajouter une option pour ajouter ou pas les méthodes __len__, __contains__ et __iter__.

Le décorateur mapping permet d'ajouter à une classe la capacité d'être utilisé comme un simili-dictionnaire. Les valeurs sont stockées dans un collections.defaultdict inaccessible pour éviter toute mauvaise intervention, mais qui peut être passé en paramètre pour une gestion déportée. Les deux autres paramètres indiquent si le dictionnaire doit être éditable ou non (ajout des méthodes clear, __setitem__ et __delitem__), et s'il doit être étirable, et si oui, sur ses keys, values ou items. La méthode __contains__ est définie en fonction de ce dernier paramètre, et la méthode __len__ n'est fournie que si le dictionnaire est itérable (voir pourquoi).

La méthode habituelle get d'un dictionnaire, qui permet de fournir une valeur par défaut si la clef indiquée n'est pas présente, n'est ici pas fournie, mais remplacée par deux autres méthodes : check et parse. La première passe en revue un certain nombre de clefs et renvoie la première valeur trouvée, ou None s'il n'y en a aucune, sans générer d'erreurs. La seconde permet d'utiliser le parseur du module types pour obtenir la valeur au format désiré (None sera parsé si elle n'est pas présente).

Enfin, la méthode __getitem__ utilise une récupération « intelligente » des valeurs : on considère que les clefs seront soit de type str, soit de type int. Si la clef fournie est un générateur ou une collection classique, on renverra toutes les valeurs correspondantes, avec le même type (l'exception KeyError étant déclenchée à la première clef manquante). Une méthode supplémentaire « fetch » permet de générer un couple (clef, valeur) pour chaque clef fournie, permettant ensuite de créer un véritable dictionnaire si besoin.

Le décorateur listing présente un fonctionnement analogue, mais pour émuler un itérable indexé (liste, tuple) plutôt qu'un dictionnaire. La classe résultante est donc toujours itérable, mais peut, ou non, être éditable.

Le décorateur listenable permet de rendre un objet « écoutable », en lui ajoutant les méthodes suivantes :

Une fonction peut être passée à listenable avec l'argument spécial « tapping » pour déclencher des traitements particuliers lors du (dé)référencement d'une fonction d'écoute.