Ce qui suit devrait être plus explicite.
Instance, classe et métaclasse
Une classe est ainsi une instance de la classe type.
Tu pourrais explicité cela. En effet, si la notion de type est assez intuitive (un nombre n'est pas la même chose qu'une chaîne), le rapport avec les classes (5
est une instance de int
, par exemple) est, je pense, moins connu.
Peut-être d'ailleurs pourrais-tu commencer par là, ayant ainsi le raisonnement suivant :
- En Python, tous les objets ont un type
- Exemples simples (entiers, chaînes, etc.), en utilisant juste la fonction
type
- Mais, pour un objet, être du type
T
revient à être une instance de cette classeT
- Or une classe est un objet comme un autre
- Donc quelle est la classe d'une classe (son type) ?
D'ailleurs, y a-t-il une différence entre "être du type T
" et "hériter de la classe T
" ? Quid des héritages multiples ?
Quel est donc ce type ?
Une chaîne de caractères représentant le nom de la classe ;
Je ne comprends pas tellement l'intérêt vu qu'on stocke la classe dans une variable : A = type(...)
.
Le dictionnaire des attributs et méthodes de la classe.
Peut-on renseigner des attributs et méthodes de classes ou statiques ?
Le vrai constructeur
Nous choisissons ici de faire appel à object.new dans notre constructeur (via super), mais nous n'y sommes pas obligés.
Peut-être cela a-t-il plus sa place dans un tutoriel sur la POO, mais aurais-tu un exemple concret où MaClasse.__new__
ne fait pas appel à object.__new__
?
Les métaclasses
Puisque nous voulons altérer la création et non l'initialisation, c'est dans le constructeur que le tout va s'opérer.
J'ai un peu bloqué là-dessus, puisque je me suis dit que ce n'est pas la création de la métaclasse qu'on souhaite altérer, mais celle de la classe. Du coup, je ne comprends pas tellement pourquoi on modifie le constructeur de la métaclasse.
>>> class M(type):
Tu pourrais faire autre chose dans le __new__
, même si c'est bidon. Là, M
ne sert à rien d'autre que montrer la syntaxe. Par exemple, Sam illustre ça en créant une métaclasse qui préfixe tous les noms d'attributs et de méthodes.
Cette méthode doit toutefois retourner un dictionnaire ou objet similaire.
Par "objet similaire", tu veux dire "objet indexable (par des chaînes ?)" ?
Les énumérations en Python sont implémentées à l'aide de métaclasses.
Peut-être pourrais-tu redonner le lien fourni dans la première section ?
Une implémentation simplifiée possible d'Enum est la suivante :
J'ai vraiment du mal avec cet exemple. N'y aurait-il pas moyen de le simplifier en enlevant le cache ?
Utiliser une fonction comme métaclasse
Ce qui fait qu'à l'héritage, l'appel à la métaclasse serait perdu
J'ai un peu bloqué là-dessus parce que tu n'as pas vraiment mis en relation l'héritage et les métaclasses.
TP : Évaluation paresseuse
Et dans notre exemple, l'objet retourné devra posséder les méthodes add et eq. Méthodes qui se chargeront d'effectuer le calcul du carré.
Ce ne sont ici que deux opérateurs, mais il en existe beaucoup d'autres, dont l'énumération serait inutile et fastidieuse, et il va nous falloir tous les gérer.
A la première lecture, j'ai eu un peu de mal là-dessus. Peut-être pourrais-tu clarifier en disant explicitement qu'on souhaite exécuter la fonction (calculer le carré) lorsqu'on applique un opérateur sur notre objet, ou plus généralement, qu'on souhaite exécuter l'expression lorsqu'on appelle une méthode de l'objet.
Merci.