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.
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 :
listen
référence une fonction d'écoute. Peut être utilisée comme décorateur. Les paramètres supplémentaires seront passés à la fonction lors de ses appels.listenonce
analogue à la précédente, mais la fonction d'écoute est automatiquement déréférencée juste après son premier appel.unlisten
déréférence une fonction d'écoute. La fonction doit être fournie avec les mêmes paramètres que lors de son ajout.audience
liste les fonctions d'écoutes actuellement références, avec leurs paramètres (il s'agit donc d'un tuple de tuples (funct, args, kwargs), le dernier étant converti en frozendict pour éviter l'ingérence).tapped
indique si des fonctions d'écoutes sont actuellement référencées. Renvoie vrai si c'est le cas, faux si l'objet a déjà été écouté mais ne l'est plus actuellement, et None
s'il n'a encore jamais été écouté.noise
permet de déclencher un appel aux les fonctions d'écoute. Cette fonction prend un nombre de paramètres qui est fourni comme premier paramètre à listenable
(des paramètres supplémentaires peuvent leur donner des valeurs par défaut). En cas d'exception sur une des fonctions d'écoute, la trace est affichée sur la sortie d'erreur, mais l'exécution n'est pas interrompue.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.