Session du 15 janvier 2025 à 21h00
Veille & Discussions
Deviens membre Premium magic_button
Cette session de mentorat est réservée aux membres Premium. Rejoignez-nous pour accéder à toutes les rediffusions des sessions de mentorat !
Premium
- check +100h de formations
- check +180 exercices de code
- check +100h de mentorats en rediffusion
- check 20 projets
- check Mentorats groupés hebdomadaires
- check Support individuel avec nos mentors
Session de mentorat TOSA sur les descripteurs
Session de mentorat TOSA pour prendre en main la notion de descripteurs en Python.
00:00:00 :Nan Tiere!Gwenit!!Ah oui c'est travail...Bonne soirée!Bonne soirée Tiere!Bonne soirée!Voilà donc tout le monde est rentré, parfait, donc bienvenue et bonne année à tous et toutesparce que je ne vous ai pas encore vus cette année et puis donc ce soir on va changer des
00:00:35 :habitudes, c'est vrai que j'avais tendance à faire des sessions que j'appelais foire auxquestions et en discutant avec Thibaut récemment, il nous a dit que beaucoup de gens allaientpasser de ça prochainement et que ce serait bien pendant une période d'intensifier et d'avoiressentiellement des sujets sur les fondamentaux de Piton et c'est pour ça qu'aujourd'hui j'ai
00:01:03 :décidé de vous parler des descripteurs. Donc les descripteurs c'est quelque chose qu'on utiliseparfois ou assez souvent même sans le savoir parce qu'un mécanisme qui est vraiment au centre dufonctionnement des classes de Django mais on l'utilise de manière indirecte la plupart dutemps. En effet quand vous faites de la programmation orientée objet avec des classes, vous
00:01:32 :utilisez parfois ce qu'on appelle des properties avec le décorateur at property, vous utilisez desfonctions, des méthodes, donc les fonctions hors d'une classe mais la fonction dans une classe quidevient une méthode et cette méthode peut être une méthode d'instance, une méthode de classe ou uneméthode statique. Et le mécanisme derrière tout ça, à l'interne de Piton, utilise un concept qu'on
00:02:01 :appelle les descripteurs. Les descripteurs servent à Piton lui-même pour son implémentation internemais également peuvent nous servir pour d'autres choses. Par exemple pour ceux d'entre vous qui font
00:02:15 :du Django et qui utilisent ce qu'on appelle des modèles en Django pour décrire la base de données,finalement il y a pas mal de mécanismes là derrière sous le capot qui fait appel aux descripteurs. Donc
00:02:29 :on va essayer de voir aujourd'hui simplement ce que sont les descripteurs, à quoi ça peut servir etcomment se documenter dessus au sein de la documentation officielle de Django. Je vais
00:02:42 :partager l'écran et on va directement partir dans le vif du sujet, si mon ordinateur me laisse lefaire. Alors à partir de là, si mon partage est en succès, vous devriez voir en navigateur avec
00:03:02 :Google Collaboratory à l'intérieur et donc un document DocStream Montora Descriptor.Est-ce que vous voyez bien mon écran ? Oui c'est bon. Oui on voit bien. Oui parfait,
00:03:16 :merci. Donc on va partir très simplement avec une classe vraiment basique, par exemple uneclasse que je vais appeler A. Ici je vais pas trop me fouler et ici on va simplement définir
00:03:31 :un attribut de classe qu'on va appeler X. Et puis X, je vais non plus pas beaucoup me fouler,je vais lui donner une certaine valeur, prenons 77, une excellente année. Et ici on va simplement
00:03:49 :créer un objet à partir de cette classe. Pour créer un objet, simplement on va instancier laclasse A et puis ensuite accéder à A.X. C'est ce mécanisme, vous le connaissez très bien.
00:04:01 :Donc vous connaissez le mécanisme des attributs de classe ou le mécanisme des attributs d'instance.Pour créer un attribut d'instance, il faut qu'on crée une méthode, par exemple une méthoded'initialisation ici et puis ici je pourrais effectivement créer un attribut d'instance lemême mais défini au niveau de l'instance d'ailleurs. Deux mécanismes différents. Mais
00:04:29 :on a un autre mécanisme si on veut créer des attributs qu'on pourrait qualifier d'intelligent.Alors tout d'abord on va définir un attribut Y ici et de manière pas la plus intelligente qui soitmais de manière inutilement complexe on va créer un attribut qui fait la même chose. Ici qui
00:04:51 :retourne 77. Alors comment est-ce qu'on peut faire autrement que comme ça ? Alors on va utiliserpour ça ce qu'on appelle un descripteur. Donc un descripteur ici c'est simplement une classe
00:05:07 :qui aura un nom. Alors ici 77. Puisque je suis suisse on va aller sur 70. C'est moins long àécrire que 77 et beaucoup plus logique pour le coup. Et qu'est-ce qu'un descripteur ? Un
00:05:25 :descripteur c'est une classe qui possède au minimum une méthode qui s'appelle Get. Et quipossède trois paramètres Self. Ici un paramètre qui s'appellera Obs. Et puis Obs.Type. Et puis
00:05:44 :ce paramètre Obs.Type généralement il est optionnel. Essayons de voir ce qui se passe si ici je faisun return de 77. Alors 77. Donc c'est une classe qui retourne uniquement 77. On est d'accord ça
00:06:05 :sert à rien mais c'est pour voir le mécanisme. Donc ici si je crée un deuxième attribut declasse mais cette fois plutôt que de lui donner la valeur 77 ici, on va lui donner donc 77 et puison va instancier. Donc si on donne, on instancie un descripteur et on attribue sa valeur en attribut
00:06:33 :de classe par exemple. Le simple fait maintenant d'appeler l'attribut Y ici va aller exécuter laméthode __Get__ ce qu'on appelle un dunder en python. Donc la méthode Get__. Et ici on va retrouver notre 77.
00:06:56 :Pour vous prouver que ce 77 vient bien de cette méthode, on peut aller mettre une trace avec un petit print iciqui nous dit ici dans la méthode Get__. Et pour le coup si j'accède ici à ce paramètre Y, non seulement il va me retourner
00:07:20 :la valeur, la valeur qui est retournée par ce descripteur, mais également il va exécuter ceci.Ok donc ici on voit que j'ai un objet qui est en attribut de ma classe A et auquel je peux accédercomme si c'était en attribut. Mais dans les faits je vais accéder à une méthode, cette méthode s'appelle
00:07:52 :Get__ ici. Ceci doit vous faire probablement penser un mécanisme que vous connaissez déjà, par exemple le mécanismedes properties. Par exemple si maintenant je crée une méthode que j'appelle Z ici, Z self, et puis qui retourne 77
00:08:19 :et que j'utilise en décorateur ici qui s'appelle Properties. Ici c'est une surprise mais j'obtiens exactement le même comportement.Et on peut voir ici que c'est bien cette méthode qui est exécutée et ici Print ici dans la méthode Z.
00:08:58 :Donc si je résume, on a ici plusieurs attributs de la classe A, un attribut complètement standard auquel on a attribuéune constante numérique ici en int avec la valeur 77. Le Y c'est un descripteur qui va permettre d'obtenir la valeur de Y à partir d'une méthode
00:09:29 :et le Z c'est une propertie qui permet d'obtenir également la valeur 77 à partir d'une méthode. En fait une propertie c'est un descripteur.Donc le mécanisme des descripteurs c'est le mécanisme qui est derrière par exemple les properties. Mais pas que.
00:09:50 :Par exemple c'est également le mécanisme qui va driver tous les décorateurs par exemple comme ClassMéthode.Vous avez déjà vu ClassMéthode ou StaticMéthode etc. Alors StaticMéthode je ne conseille absolument pas d'utiliser
00:10:05 :mais ici vous avez plein de mécanismes en Python qui dépendent des décorateurs.Donc ici on voit qu'on a plusieurs moyens de faire la même chose. On peut se demander à quoi ça sert d'avoir toutes ces façons
00:10:23 :de définir des attributs sur une classe. Et donc il y a plusieurs cas d'usage qu'on peut attribuer au décorateur, au descripteur pardon,et on va essayer d'en voir un ou deux. Donc l'idée des descripteurs c'est de pouvoir éventuellement faire ce qu'on pourrait qualifier
00:10:47 :comme des attributs intelligents. Ici on n'a pas vu l'entier de l'équation, ici on a ce A.X, ici on pourrait rajouter encore A.Y et A.Zmais une manière de faire qui vous vient peut-être à l'esprit c'est simplement de créer une méthode, alors ABCD, comme lettre elle est en V,ici et return 77. Alors si maintenant je définis une méthode comme celle-là, alors bien sûr c'est une méthode, c'est un attribut,
00:11:29 :mais un petit peu particulier, donc c'est un attribut exécutable et pour le coup je peux appeler V, mais pour appeler V, puisque V est une méthode,je suis obligé de lui mettre des parenthèses pour exécuter cette méthode. Donc ici on voit une différence fondamentale.
00:11:48 :V est une méthode, si je prends l'objet A ici et j'appelle dessus la méthode V, je suis obligé de mettre des parenthèses.Tandis qu'avec l'attribut standard, pas besoin de parenthèses, la valeur 77 est directement attribuée à cet attribut-là.
00:12:11 :Pareil pour l'attribut Y qui est associé à un descripteur et à l'intérieur de ce descripteur on a la méthode get qui est appelée,et la même chose, dès que j'appelle ou que j'utilise cet attribut Y, pas besoin de parenthèses.
00:12:30 :Pareil pour la property Z, je peux l'utiliser sans complication, en prétendant qu'il s'agit d'un attribut alors qu'en fait il s'agit d'une méthode.Par contre V est une méthode, mais on n'a mis en place aucun mécanisme pour prétendre que ce n'est pas une méthode.
00:12:53 :Donc ici vous avez un paysage complet de comment on peut définir un attribut sur une classe.Maintenant on va essayer de voir ensemble pourquoi faire ce genre de choses.
00:13:05 :Alors il y a plusieurs cas d'usage, certains qui peuvent être faits avec des properties simplement.Les properties sont là pour simplifier l'usage des descripteurs, mais les descripteurs sont plus généraux qu'une property.
00:13:24 :L'idée c'est de faire des attributs qu'on pourrait qualifier d'intelligents.Qu'est-ce qu'on pourrait imaginer comme attribut intelligent ?Prenons par exemple une classe qui représenterait un répertoire.
00:13:40 :Ici je vais l'appeler répertoire ou directory en anglais.Une classe qui représente un répertoire.Comment est-ce qu'on pourrait imaginer une classe qui représente un répertoire ?
00:13:54 :Dans Google Collaboratory il y a la technologie artificielle qui vend la mèche, je ne vais pas faire comme elle veut.Comment est-ce qu'on pourrait représenter un répertoire ?
00:14:05 :On pourrait imaginer un constructeur qui prend en paramètre, par exemple, le nom d'un répertoire.Dire nez, dire nez.Alors, nom répertoire.Notre instance va simplement, on va enregistrer le nom et puis ce sera le nom de notre répertoire.
00:14:37 :On crée un attribut d'instance qui représente notre répertoire.Ici je peux aller représenter un répertoire qui existe ou qui n'existe pas.Je pourrais représenter un répertoire ici, répertoire.
00:14:56 :Et puis lui donner le nom de répertoire.Comment je pourrais l'appeler ? Test ou exemple.Et puis, ici, je vais lui attribuer ici, exemple.Je pourrais regarder ici à la racine.
00:15:18 :Créer un répertoire exemple qui pourrait être associé à ça.Alors, ici, qu'est-ce que je pourrais vouloir faire avec ça ?Peut-être, imaginons que ce répertoire exemple, je veux pouvoir en demander la taille.
00:15:34 :Qu'est-ce que ça peut vouloir dire, la taille d'un répertoire ?Typiquement, la taille de répertoire pourrait être le nombre de fichiers contenus à l'intérieur de ce répertoire.
00:15:49 :Alors, évidemment, là je ne peux plus, maintenant, je ne peux plus me créer simplement un truc de tailleet puis lui donner une valeur constante, comme je l'ai fait plus haut avec mon X, Y, Z.
00:16:04 :Je pourrais, bien sûr, me faire une méthode qui serait calculer taille, par exemple.Quand on crée une méthode, j'ai l'habitude de plutôt démarrer avec un verbe d'action, calculer taille.
00:16:23 :Et puis, ici, cette méthode va retourner, retourne le nombre de fichiers dans le répertoire.Comme ça, et puis, je ne veux pas tout ça.Il n'y a aucune méthode qui fait ça.
00:16:42 :Bien sûr, si je crée cette méthode-là, je pourrais l'appeler calculer taille.Et puis, il va m'appeler ça.Alors, c'est possible, c'est une possibilité.Donc, quand vous imaginez comment vous allez utiliser vos objets, vous vous demandez,est-ce que ça fait plus de sens d'utiliser une méthode ou un attribut ?
00:17:10 :À ce niveau-là, c'est vraiment très stylistique.Je dirais que si je dois choisir ce qu'on va appeler l'interface de ma classe, ça fait autant de sens,soit d'utiliser une méthode calculer taille, ici, qui retournera, par exemple, le nombre,vraiment en entier, qui représente le nombre de fichiers qui est à l'intérieur de mon répertoire.
00:17:31 :Ou alors, un attribut taille qui fait la même chose.Et finalement, l'utilisateur de la classe, lui, s'en fout de comment vous faites.Donc, lui, il appelle une méthode ou il appelle un attribut.
00:17:43 :Et puis, ce qui intéresse, c'est d'obtenir la taille et, finalement, le nombre de fichiers dans le répertoire.Alors, les descripteurs sont une manière, par exemple, d'associer un comportement intelligent à ceci.
00:17:58 :Donc, si vous voulez quelque chose de simple, comme, OK, je veux que mon objet puisse avoir un attribut taille,mais je ne veux pas définir dans ma classe, simplement, ici, self.taille,
00:18:10 :et puis, ici, aller implémenter la logique au niveau de mon constructeur pour obtenir la taille de mon fichieret devoir la mettre à jour à chaque fois, ce que je veux faire, c'est la calculer dynamiquement.
00:18:22 :Je voudrais un attribut, ici, taille, qui va percher dans le répertoireet regarde, par exemple, dynamiquement le nombre de fichiers qui s'y trouvent.Et donc, finalement, ce que je veux faire, c'est associer un comportement à ça.
00:18:37 :Donc, finalement, ce que je veux faire, c'est comme une méthode.J'ai le choix de faire une méthode, et ce sera tout à fait OK si vous le faites,mais, parfois, vous voulez offrir une interface relativement simple aux utilisateurs de votre classe.
00:18:51 :Et c'est là que, par exemple, les descripteurs peuvent intervenir.Alors, si, ici, je veux créer un descripteur.Imaginons qu'on crée un descripteur qui s'appelle taille-répertoire.
00:19:06 :Donc, ici, j'ai une classe qui s'appelle taille-répertoire et qui va posséder une méthode get.Et cette méthode get, elle va faire plus ou moins la même chose que ce que j'aurais fait avec calculer taille, ici.
00:19:23 :Donc, je vais plutôt même définir ça juste avant ma classe répertoire.Donc, obj et puis obj type.Et puis, ici, cette méthode get, elle va faire exactement ça, ici.
00:19:40 :Retourne le nombre de fichiers dans le répertoire qui est associé ici plus haut.Donc, je dois définir ou décider qu'est-ce que je vais faire ou comment je vais obtenir cette taille.
00:19:54 :Vous avez plusieurs possibilités d'obtenir le nombre de fichiers dans un répertoire.Par exemple, ce que je recommande, c'est d'utiliser, par exemple, passe libre.Vous avez aussi la possibilité d'utiliser le module OS.
00:20:08 :Vous pouvez utiliser les deux.Pour manipuler les fichiers répertoires, j'utiliserai systématiquement passe libre maintenant en 2024.Bien que vous trouviez encore pas mal d'exemples, de vieux exemples qui utilisent OS.pass pour ceux-ci.
00:20:24 :Donc, moi, on va se la jouer moderne, ici.Et puis, on va utiliser passe libre.Alors, avec passe libre, déjà, ici, comment ça va se passer ?
00:20:37 :Alors, avant de jouer et d'implémenter ça, on va regarder comment ça va être utilisé.Donc, ici, ça va être utilisé de la manière suivante.Je vais définir en attribut taille.
00:20:46 :Et puis, simplement, je vais définir ici.Je vais instantier mon descripteur taille répertoire.Et ensuite, c'est le descripteur qui fera le travail au moment où je vais appeler cette taille.
00:21:00 :Alors, j'ai vu qu'il y a quelqu'un qui est rentré.Il faut juste que je le fasse rentrer.Excusez-moi.Voilà.Donc, ici, il faut juste que je fasse le travail à l'intérieur de cette méthode get pour obtenir la taille des répertoires.
00:21:19 :Alors, on peut utiliser, par exemple, tout d'abord, si j'utilise passe libre, je peux utiliser l'objet passe.Alors, on peut directement l'apporter ici, plutôt from, passe libre, import, passe.
00:21:33 :Et avec passe, vous pouvez transformer un chemin.Vous allez recevoir ici, l'objet que vous allez recevoir ici sera l'instance de ce répertoire.Et l'instance de ce répertoire possède un attribut d'instance qui s'appelle nom.
00:21:58 :Alors, c'est ça qu'on va faire.On va prendre obj.nom.Donc, l'objet qui sera l'instance de ce répertoire, .nom, qui sera le nom de mon répertoire.
00:22:07 :Et ça, je le transforme en passe.Une fois que je l'ai transformé en passe, s'il existe, je vais utiliser la méthode qui s'appelle iterdir,qui permet d'itérer sur les fichiers contenus dans un répertoire.
00:22:20 :Et comme ça, ça retourne en itérateur.J'ai vu qu'il n'y a pas si longtemps que vous avez parlé des itérateurs.Alors, ça, ça retourne en itérateur.
00:22:30 :Ce que je vais faire, c'est transformer cet itérateur en liste.Ici, on retourne ça en liste.Et puis, une fois que j'ai la liste, j'en veux la longueur.
00:22:43 :Je veux le nombre de fichiers à l'intérieur de mon répertoire.Donc, je peux prendre la longueur ici autour.Vous pouvez le faire en plusieurs étapes, si vous voulez.
00:22:53 :Vous pouvez très bien définir votre itérateur.Ensuite, vous pouvez obtenir un liste, un fichier, par exemple.Ici, c'est transformer votre itérateur en liste.Et puis, ensuite, vous retournez, par exemple, la longueur en faisant un len de liste fichier.
00:23:18 :Puis, vous avez votre truc.Ici, vous voulez le faire en trois étapes, parce que vous êtes plus à l'aise.La règle d'or en Python, c'est que la solution la plus lisible est la meilleure.
00:23:31 :Donc ici, vous pouvez garder la solution la plus lisible.Ou alors, ici, on reste encore dans un one-liner qui est relativement lisible.Mais n'hésitez pas de votre côté, si vous refaites ça,à essayer d'obtenir le nombre de fichiers dans un répertoire avec passe libreet de répéter ça soit en une ligne, soit en plusieurs lignes.
00:23:55 :Alors ici, je vais le faire en une ligne.Donc, j'ai un descripteur dont la méthode get va me retourner le nombre de fichiers dans mon répertoire.
00:24:05 :Et puis, dans ma classe répertoire, j'ai un attribut taillequi lui va être une instance de ce descripteur-là.Donc, au moment où je crée un répertoire exemple ici et que je calcule la taille,il ne va pas fonctionner pour la raison simple,c'est que pour l'instant, mon répertoire exemple n'existe pas.
00:24:26 :Donc, évidemment, déjà en cette méthode-là, il ne fait rien.Et puis ici, il ne fait rien parce que exemple ne fait rien.OK. Donc maintenant, commençons pour faire un petit test.
00:24:39 :Ben, créons ce répertoire.Alors ici, on va créer notre répertoire exemple.Alors ici, on va l'appeler test dire.Test dire. Je vais utiliser passe libre pour ça.
00:24:57 :Donc, passe.Ici, je vais l'appeler exemple.Et puis, s'il n'existe pas, je vais le créer.Donc, test dire.Et pour le créer, on utilise la méthode mkdir.
00:25:19 :Ici, ça va créer ce répertoire.Et s'il existe, alors s'il existe, on va désactiver les erreurs.Donc, il existe. OK.Il y a le trou.
00:25:33 :Il va juste accepter que s'il existe, il ne va pas crier au désespoir.Et ce test dire, ici, ça va juste créer un répertoire exemple dans le répertoire courant.
00:25:48 :Ça, je l'ai fait en code.Donc, maintenant que ce répertoire là existe, si je ne me suis pas planté,la taille de ce répertoire est de zéro.
00:25:57 :Évidemment, parce que je n'ai pas encore mis ce fichier à l'intérieur de ce répertoire.Est-ce que je peux voir ici ?Voilà, on voit ce répertoire exemple et il est vide.
00:26:07 :D'ailleurs, j'aurais pu me passer de ce code là et simplement créer un fichier à l'intérieur.OK. Donc, maintenant, on voit qu'ici, je n'ai rien eu à faire.
00:26:19 :Je n'ai pas eu de logique à ajouter dans ma classe pour qu'il ait exercé cette taille.En fait, toute la logique est à l'intérieur de notre descripteur et de la méthode get de notre descripteur.
00:26:34 :Ici, ajoutons un fichier pour vérifier qu'il va bien trouver les choses.Donc, ici, dans exemple, est-ce que j'ai un moyen de le faire relativement simple ?
00:26:44 :New file et puis on va l'appeler fichier 1, fichier 1.txt par exemple.Donc, il contient un fichier et puis peut-être enlever les différents trucs.Est-ce qu'il va me retourner 2 ? Alors, on va voir.
00:27:04 :Donc là, on voit que j'ai ajouté un fichier et sans rien modifier à ma classe, il me retourne taille 2.Donc ici, on a l'impression que j'appelle effectivement un attribut de ma classe,mais on voit qu'il est intelligent, dynamique, c'est-à-dire au fur et à mesure que j'ajoute des fichiers,
00:27:23 :il agit comme si c'était une méthode, sauf que je n'ai pas besoin de l'appeler comme une méthode.Donc, l'utilisateur de la classe a l'impression que c'est juste un attribut,mais cet attribut réalise une action qui, potentiellement, est complexe.
00:27:42 :Donc ça, c'est le mécanisme des descripteurs.Ici, c'est d'avoir un attribut qui fait un travail complexe,plus complexe que simplement ce qu'on avait au départ,c'est-à-dire que l'attribut X de la classe A retourne une valeur constante, 77.
00:28:04 :Ici, on se retrouve avec une classe répertoire dont l'attribut taille fait un travail conséquent,et ce travail, j'ai pu l'externaliser à l'extérieur dans un élément réutilisable éventuellement.
00:28:16 :Alors, on peut se demander si c'est réellement intéressant pour la taille d'un répertoire,de faire cela en externalisant ce comportement à l'extérieur de la classe,j'aurais très bien pu faire ici, par exemple, utiliser une propertie pour ça.
00:28:35 :Les properties, ça fait exactement la même chose.Def, taille, self pour le coup, et puis ça, je peux le copier ici,et la propertie fait presque la même chose.
00:28:52 :Pour cause, une propertie, c'est un descripteur.Ça permet de créer facilement un descripteur.Ici, je peux faire exactement la même chose avec cette propertie.Ici, simplement, la solution va être un petit peu différente.
00:29:06 :Ici, ce sera self.nom, et ici, on va avoir la logique.Ici, la logique avec la propriété, la logique se trouve directement dans la classe répertoire.
00:29:15 :Avec le descripteur qu'on a eu avant, la logique était externalisée dans une classe séparée.Toujours est-il que le résultat est relativement similaire ici,puisque du coup, ça fonctionne exactement la même chose.
00:29:31 :L'utilisateur n'y voit que du feu.Donc, vous pouvez passer de l'un à l'autre, vous pouvez faire ce que vous voulez.Ici, vous pouvez le faire sous forme d'une propertie,échanger d'avis et le faire sous forme d'un descripteur,ou commencer avec un descripteur et le transformer,si vous voyez que vous n'avez pas besoin d'un descripteur,
00:29:48 :de transformer en propriété, etc.Donc, l'utilisateur de votre classe, lui, il appellera simplement la tributaille,il ne verra que du feu.Donc, ça, c'est la bonne nouvelle.
00:29:57 :Tandis que si vous implémentez d'abord ça sous la forme de méthode,on aura un souci, parce que l'utilisateur va devoir utiliser les parenthèses,et si demain vous décidez de transformer en propriété,les parenthèses ne fonctionneront plus, ça lui posera problème.
00:30:13 :En fait, il devra enlever les parenthèses dans son code.S'il utilise la tributaille dans son code en utilisant votre bibliothèque à un endroit,ce n'est pas un problème,mais s'il l'utilise à plein d'endroits différents,ça cause un gros problème de maintenance.
00:30:27 :Donc, une fois qu'on a choisi entre méthode et propriété, on ne change plus.Tandis que là, entre propriété et descripteur, vous avez absolument le choix.
00:30:37 :N'hésitez pas, si vous avez des questions à tout moment, de les poser.Moi, j'ai une question, Thierry.En fait, j'ai compris comment il faut faire marcher le mécanisme,mais je ne comprends pas comment ça marche, en fait.
00:30:52 :Quand on appelle taille, par exemple,dans ton exemple, exemple.taille,à chaque fois qu'on fait ça, qu'est-ce qui se passe derrière ?C'est parce que là, quand tu écris taille est égale à taille répertoire parenthèse,il stocke la valeur qu'il trouve au moment où il lit ce morceau de code,
00:31:16 :il le stocke en dur, non ?Non. Alors, ici, il le fait plusieurs.Alors, quand on crée notre instance de répertoire,quand on appelle l'attribut taille,alors ici, on va être très technique,il y a une méthode spéciale des classes de Python qui est appelée,qui s'appelle getAttribute.
00:31:42 :GetAttribute va voir s'il existeune variable ou un attribut d'instance qui s'appelle taille.Dans notre cas, il n'y a pas d'attribut d'instance qui s'appelle taille.
00:31:58 :Un attribut d'instance, ici, j'aurais dû faire ça pour qu'il y ait un attribut d'instance.Ici, pour l'instant, j'ai un attribut de classe.D'abord, il regarde s'il y a un attribut d'instance qui s'appelle taille.
00:32:11 :Ensuite, il simplifie, il va aller regarder s'il y a un attribut,ici, de classe qui s'appelle taille.Alors là, pour le coup, il va le trouver.
00:32:23 :Et une fois qu'il a trouvé cet attribut d'instance,il va regarder ce qu'est cet attribut.Est-ce que c'est une méthode ? Est-ce que c'est un objet ?
00:32:33 :Est-ce que c'est un objet ? Est-ce que c'est un descripteur ou c'est pas un descripteur ?Si j'avais en dur mis taille égale 2, pour l'exemple.
00:32:42 :Il aurait trouvé l'attribut taille.Il a vu que cet attribut taille est associé à un objet.Cet objet, ici, c'est un entier de type int.
00:32:53 :C'est un objet. En Python, tout est un objet.Donc le 2, aussi, que vous voyez ici, c'est aussi un objet.C'est aussi l'instance d'une classe.
00:33:01 :Ici, l'instance de la classe entier ou int.Donc c'est un objet, mais c'est pas un descripteur.Donc il va retourner directement cette valeur.Tandis que si Python voit, ok,l'attribut taille est associé à un objet,cet objet est un descripteur.
00:33:20 :Comment il sait que c'est un descripteur ?Il va voir que cet objet a une méthode get.C'est très facile de voir.Ici, répertoire.Est-ce que la classe répertoire a un objet taille ?
00:33:36 :Je peux utiliser as at répertoire taille.Oui, il a un taille répertoire.Pourquoi il dit non ?Bon alors, on va aller directement...Je peux vous ajouter la cellule ?
00:34:04 :Parce que là, il doit avoir...Il a un répertoire, il a un taille.Ok ?S'il trouve taille dans répertoire,il va regarder ce qu'est taille.
00:34:17 :Donc du coup, on peut regarder ce que répertoire,répertoire.taille, contient comme méthode.On voit qu'il en contient beaucoup.Mais normalement, dans ces méthodes-là,vous avez une méthode get, qui est celle qu'on a.
00:34:41 :Alors, pourquoi est-ce qu'il ne la trouve pas ?Est-ce que j'ai...Quelle taille...Je l'ai défini, bien sûr, taille, comme ça.Voilà, pardon.Et taille, et ensuite, répertoire, exemple.
00:35:06 :Et puis, voilà.Non, toujours pas.Je vais...Ou réexécuter, ce sera plus simple.S, nom, attribut, nom.Et pour le coup, je ne l'ai pas rechangé.
00:35:31 :Attribut, objet, nom.S, nom, parce que...Ici, ce n'est pas...C'est exemple.taille.Voilà.Est-ce que je trouve ma méthode get ?Toujours pas.Je vais verrer ce mécanisme.
00:35:55 :Donc, à un moment donné, quand il trouve taille,il a un moyen pour savoir que ça,que l'objet qui est associé à taille,c'est un descripteur.
00:36:07 :Et s'il trouve que c'est un descripteur,alors il va appeler sa méthode get.Tandis que s'il trouve que c'est n'importe quelle autre valeur,il va simplement retourner sa valeur.
00:36:17 :Donc, il y va par étage, comme ça.Il y va par étage, ce qui lui permetde faire l'action qui est nécessaire.Et donc, c'est une chaîne d'actionqui est implémentée, alors, pour le coup,ici, vous avez une classe,en Python, en fait, implicitement,un read de object.
00:36:43 :Alors ça, vous ne devriez jamais le mettre en Python 3.Mais il peut y avoir ces objectsqui implémentent un certain nombre de méthodesqui sont utilisées par Python,en 3.100, pour définir tous ces mécanismes.
00:36:58 :Et ces mécanismes-là sont définispar, justement, la méthode getAttributede object.Donc, quand je fais un appel comme celui-là,je fais un appel comme, ici,exemple.tie.
00:37:16 :Il y a toute une chaîne de choses.Il y a exécution de la méthode getAttributed'exemple, qui va chercher s'il existeen attribut tie.Et donc, il va regarder s'il existeen attribut d'instance, tie,puis en attribut de classe, tie.
00:37:32 :Et s'il y en a un, quel est l'objetqu'il lui a attribué, et si cet objetest un destructeur, c'est-à-direau moins une méthode get.
00:37:40 :Là, il va appliquer, exécuterla méthode get implicitement.Et on peut regarder ce que cette méthodeget reçoit.Ici, si je fais un print de obj,et puis un printde obj type, par exemple,et qu'on réexécute tout ça,on voit que lorsque j'accède,par exemple, tie,il reçoit, en tant que obj,
00:38:07 :il reçoit le répertoire qui a été créé,donc notre répertoire exemple.Si on veut vraiment pouvoir visualiser ça,probablement qu'on doit,ici, si je mets,je ne sais pas si vous avez déjà rep,c'est une méthode qui nous permetde voir la représentationtextuelle de cette classe.
00:38:29 :Ça rendra peut-être les choses plus visibles.Donc ici, on voit que quand j'accède tie,il reçoit comme obj le répertoire exemple,et il reçoit comme obj typela classe répertoire.
00:38:45 :Et puis il retourne ensuite,ici, la longueur du répertoirequi est de 2.Donc voilà ce qui est faitmécanistiquement du point de vue de Python.
00:39:01 :Du coup, c'est impossible de stockercette valeur à un instant donné, alors ?Parce qu'à chaque fois qu'on appelle tie,on va refaire ce mécanisme.
00:39:13 :Ce serait possible.Est-ce que ce serait souhaitable ?Ce serait une autre chose.Mais ici, si je veux stocker à l'intérieur de çala valeur qui a été obtenue la dernière fois,avoir un système de cache, par exemple,je peux stocker la valeurdirectement là-dedans, par exemple.
00:39:33 :Donc si j'ai ici récupéré,on peut mettrelast value ou value.Je peux la stocker ici.Et ensuite, par exemple, on pourrait imaginercomment le faire ?
00:39:54 :Je pense comme ça.Et puis ici, on va retournerself.value.Voilà.Ici, on pourrait avoir un mécanismeself.value.On va faire ça comme ça.C'est une classe, donc je peux mettreun init ici.
00:40:22 :self.value égal none.Et puis ici,if self.valueici is none.Parce qu'on calculecette valeur et on retourne.Donc c'est un système de mise en cache.
00:40:44 :Donc ici, il ferait la même chose,mais il calcule juste la taille la première fois.On pourrait imaginer qu'après,il la recalcule que si elle a changé de valeur,mais pour savoir si elle a changé de valeur,je suis obligé de la calculer.
00:40:56 :Donc ça, c'est ce qu'on pourrait appelerun descripteur avec un mécanisme de cache.Donc dans notre cas de figure,ça fonctionnerait.Donc ici, on peut voir que ça fonctionneen exécutant tout mon code.
00:41:13 :Il retourne 2.La même chose, je vais éliminer un petit peupour y voir plus clair.Donc il retourne 2 toujours.Maintenant, si je viens ajouterdans ce répertoire, exemple, un nouveau fichier.
00:41:28 :New file fichier2.txtça devrait lui faire retourner 3.Et que je réexécutemon code.Et que maintenant, je réexécute ça.Je rajoute le fichier,mais je réexécute pas tout le code.
00:41:49 :Juste le dernier taille.Donc ici, fichier4.txtEt ici, il réexécute juste taille.Il ne me met plus à jour le truc.Parce que j'ai sauvegardé la mémoire.
00:42:05 :J'ai sauvegardé la valeur précédente.Donc je peux sauvegarder une valeur.Dans le cadre decet exemple là,ça fait pas de sens de mettre en cacheune valeur, mais c'esteffectivement, il y a possibilitéde sauvegarder la valeur.
00:42:25 :Donc il va pas chaque foisla calculer.Donc techniquement,une manière simple de le faire,c'est de sauvegarder la valeur directementdans le descripteur, et une foisqu'elle a été attribuée, si je veuxajouter un mécanisme de cache,je peux effectivementle faire de cette manière là.
00:42:45 :C'est une manière de faire.J'aurais aussi pufaire que je viensremplacer...Je viens définirune valeur tailledirectement sur l'objet.C'est aussi possible.Plutôt que d'avoir cette valeur là,je peuxdans ce que je pourrais faire,on va s'éloigner un petit peu du truc,je peux aller sur obj,
00:43:17 :ajouter obj, c'est notre objetrépertoire, et je peux aller lui ajouterune variable d'instancequi s'appellerait taille, qui sauvegarderait la valeurde la taille, et donc on partiraitavec taille qui est dynamique, et puisensuite, ce serait une valeur rendue.
00:43:31 :Il y a en Python, en propertyqui s'appelle cacheproperty,doncfonction qui fait exactement ce typede truc.C'est dans funtools,et puis c'est cache,direct, cache property.
00:43:57 :Cache propertyc'est comme une property, c'est comme une propriété,mais une fois qu'elle a été calculée une fois,il garde la valeur qu'il a trouvée. Ca évite
00:44:05 :qu'à chaque fois qu'on appellece paramètre,cet attribut,il soit recalculé dynamiquement à chaque fois.Mais,généralement c'est pas ce qu'on veut,donc il faut faire attention avec ça.
00:44:19 :Donc voilàavec le détail dumécanisme.Pourquoi doncfaire ça ?Quels exemples on pourrait imaginer ?Alors par exemple,pour les exemples,on peut consulter,voir ce que Python nous dit au sujet des descripteurs.
00:44:39 :Donc si je vais dans la docde Python,etvous allez à la documentation.La doc de Pythona un tuto complet sur les descripteurs.
00:44:51 :Donc elle a un chapitreautour ici. Vous avez plusieurstutos. Alors le tutoest pas complètement traduit en français, mais partiellement.Etvous avezun tuto sur les descripteurs.
00:45:05 :Ici, descripteur.Ici, descriptor guide.Donc ce guide sur les descripteurs.Alors vous retrouvezquelques exemples.Et un exemple sur lequel on va passer,c'estl'exemple par exemple des validateurs.
00:45:23 :Donc l'idéed'un validateur, c'est queje peux créerplusieurs descripteurs.Donc ici, par exempleun validateur de chaîne, un validateurde nombre. Alors qu'est-ce qu'on peut attendre
00:45:37 :d'un validateur de nombre, par exemple.On peut imaginer que vous vouliez créersur une classedesattributs, par exemple iciune quantité, et que vousvouliez que, par exempleavoir une vérificationde la valeur que vous allezaffecterà quantité.
00:45:59 :Donc je veuxfaire quepar exemple je puisse définir dans quantitéune valeur minimum ou une valeurmaximale. Pareilpour la validation d'unechaîne de caractère, peut-être que je veux créerun descripteur qui s'appelleString ici, et je voudraisque l'utilisateurqui essaye d'affecter à Nameune chaîne de caractère qui serait
00:46:23 :trop courte, ou alorstrop longue, on pourraitimaginer que dans ce cas-làil y ait une erreur.Donc créer une possibilitépourqu'on puisse validerde manière élégantece que va nous passerfinalement l'utilisateurlorsqu'il créeune instance d'une classe.
00:46:47 :Donc ici on crée une instance d'une classequi possède un attribut Name,un attribut quantité,par exemple du Bekind, etc.Et ici Namesera validé. Alors codons
00:46:59 :ensemble un tel validateur.Essayons d'aller pas par pas.Donc si je voulais créer undescripteur qui s'appelle Validateur,ouValidateur,je devraiscréer, comme on l'a vu,pourune méthode Get.
00:47:23 :Donc ici Self,Obj, ObjType,ObjType, None, et puisOK. Donc ça,déjà,ça va me permettrede, sur ma classeA, par exemple,d'ajouterun attribut, x,et puisde pouvoirle valider avec le Validateur.
00:47:59 :Alors le Validateur,et bien sûr, Validateur ne suffit pas.Peut-être que je vais créer des Validateurspersonnalisés, par exempleun Validateur Number, ici,qui hérite de Validateur,et qui va me validerici, donc l'objectifserait ici de validericiun Nombre,y comprisentre un Min et un Max.
00:48:33 :OK. Donc,on peut imaginer que ça, c'est un besoin que vous avezsouvent. Vous avez besoin,relativement souvent, peut-êtrevous avez un,je ne sais pas, vous créez un panierpour un site du commerce, ou pour une applicationde commerce,et puis vous voulez vérifierpar exemple qu'au minimum, la quantité
00:48:55 :d'un produit est de 1,et pas de 0, pas négatif.Et puis,éventuellement, vous ne voulez pas pouvoir commanderplus de 100éléments, ou alorsun Nombre maximal qui est définipar exemple par la quantité en stock.
00:49:11 :Bref, une validationde Nombre, c'est quelque chose qu'on veutsouvent pouvoir faire.Donc, ici, par exemple,créons justela validation de Nombre. Donc, je vais
00:49:23 :simplifier par rapportau guide sur les descripteurs. Si vous voulezl'exemple complet, vous pouvez utiliserle guide sur les descripteurs. Nous, ici,validation de Nombre. OK.
00:49:33 :Donc, j'ai besoin, ensuite,qu'ils puissent validerles choses à différentsmoments. Mais,en particulier,quand je vois qu'il y a une validation,quand je créeun objet, ici,obj, de type A,et puis,par exemple, quand on lui attribueun Nombre qui est trop grand,100. Donc,
00:49:59 :ici, dans ma classe,j'aiune méthoded'initialisation, et puis,on va donner une valeur de x,self.x,ici.Et je veux que, quand la valeurest plus grande que 50 oumoins que 10, il y ait une erreur.
00:50:19 :Et je veux queça se soitimplémenté à l'aide d'unvalidateur qu'on va appeler Nombre.Nombre.Et donc, ici, peut-être qu'on veutminValueégal 10,et maxValueégal 50.
00:50:41 :Et si je luiattribue un Nombre qui n'est pasdans ces conditions-là, je veuxqu'il refuse la création de l'objetou qu'il me lève une exception.
00:50:51 :Alors,essayons de voir ça.Donc,ici,j'ai plusieurs challenges,et un des challenges, c'estde pouvoir déjà stockerla valeur qui vapasser. Bien sûr, ici,
00:51:09 :on va vouloir stocker une valeur,et ça, ça va se faire avec une méthodeset. Donc, une méthodeici qu'on appelleset, et puis parfois, ondevra obtenir la valeur.
00:51:21 :Et ça, c'est get. Donc, on doitimplémenter deux méthodes. La méthode get,celle-là, on l'a déjà discutée.Cette méthodeva permettre d'obtenirla valeur de x.
00:51:35 :Et unedeuxième méthode qu'on vadevoir implémenter, c'est la méthodeset. Vous avez déjàentendu parler de getter et de setter,donc on est en plein dedans ici.
00:51:47 :Get value, ici.Donc, ici,si je faisobj.x,là, c'est le getter qui est appelé.Tandis que si je faisobj.x égaleune valeur, par exemple, 33 ici,là,c'est le setter qui va être appelé.
00:52:07 :OK ?Donc, j'ai deux méthodesici, et je vaisici pouvoirle faire. Alors ici,on vadonc, pour le get,on va retournericiobj.
00:52:27 :etx.Ici.Et ici, on varéaliserobj.xégale value.OK ? Donc, déjà,on va noter que ça fonctionne.Alors, hop,min,etc.On va ici ajouternotre init,et notre init, simplement,on va prendre la valeur min, la valeur max,comme c'est suggéré ici,et puis, pour l'instant,
00:53:05 :je vais juste éliminer çapour l'instant, parce que je ne vous ai pasencore expliqué ce que c'était.Maintenant, à partir de là,cette classe, pour l'instant,fonctionne. C'est-à-dire que
00:53:17 :qu'est-ce que je veux dire par« elle fonctionne » ? Elle fonctionnesans vraimentbeaucoup d'imagination, elle ne fait pas devérification, pour l'instant.Quand je prends l'objetet je lui demandel'attribut x,elle me retourne la valeur100 qui a été attribuée à xlors del'instantiation.
00:53:41 :Alors, attendez.OK. N'hésite pas à poser des questions.Ma question, c'estqu'au niveau du get et du setdu class number,comment dirais-je,le x,c'est par défaut, maisau niveau du get,« return obj.x »
00:54:09 :et le setobj.xest-ce qu'il y a de la valeur ?Faut savoir d'où vient le xou bien le...En fait, il va simplements'occuper de le créer. Ici,
00:54:23 :en fait, qu'est-ce qu'il se passe ?Dans ce get,quand je faisobj.get, il va aller regardersi cet objet possèdeun truc en x ici.
00:54:35 :Où est-ce que ce obj.xest créé ? Dans le set.Ici, quand j'appelle self.xégalecette valeur-là, x,c'est là quele set est créépour la première fois. Qu'est-ce qu'il fait ?
00:54:51 :Cette méthode set,elle va créerun self.xet elle va lui attribuerla valeur qui a été passée.Donc ici,la valeur reçue qui est 100.
00:55:05 :En fait,lorsque l'on a ça,on a cette méthode setqui est appelée et qui vaaller affecter la valeur reçuequi est 100à la valeur que j'ai appeléex, mais j'aurais pul'appelerprivate xsi vous préférez.
00:55:27 :Et puis,ici, du coup,je fais un appelde x et doncdu coup, c'estcette méthodeget qui va être utiliséeet va rappelerobtenirla valeur de 100.
00:55:47 :Donc ici,on peut vérifier le fonctionnementde tout ça. Donc ici,si je fais un print,on dit qu'on est dansnumbergetavecici,la valeuret puis là,on est dans numberset.
00:56:21 :Donc là, je vais recréer une celluleséparée,et puis je vais vous montrer.Maintenant, quand on instantiecette classeA,on va appeler le initet dans le init,on va attribuer une valeurà self.x.
00:56:47 :Comme ça, c'est un descripteur,ça va appeler la méthode setet donc, je vais voir affichéici, après exécuter ça,je vais voir dans number setparce queici, il y a eu attribution d'une valeurà x.
00:57:05 :Et ici, en dessous,object x,je vais avoirdans object, je cherche à avoirla valeur x,x est un descripteur,donc Python va aller chercher la méthodeget et retourner sa valeur.
00:57:21 :Donc normalement, cette méthodeva être exécutée avec le print qui est là.Et ici,on a 100.Jusqu'ici, pas de validation.On voit que je peux mettre une valeur de 100et même si cette valeur estsupérieure à 10mais également supérieure à 50,je n'ai rien qui s'est passé.
00:57:41 :Mais, du coup,je peux mettre ici une validation.Par exemple,ici, je peuxtrès bien aller mettrepar exempleif, en test,on va mettreici, clairement,if valueest plus petiteque self min valueou si la valeurest plus grande que max value,alors vous allez lever
00:58:13 :une value erreur, la valeurn'est pas comprise entre le minimumet le maximum.Donc ici,c'est ce queje fais etici, lorsque je vais instancier le truc,il va y avoir appel de la méthodeset, la valueva recevoir le 100 que j'ai mis là,le 100n'est pas compris entre la valeur
00:58:39 :minimum de 10 etla valeur maximum de 50.Donc,la validation desvaleurs va avoir lieu ici.Hop, on voitune value erreur, la valeur 100 n'est pascomprise entre 10 et 50.
00:58:55 :Donc, j'ai une validation.Donc, monvalidateur fonctionne.Je peux créer un validateur pourles nombres, pour les chaînes de caractère,pour les numéros de téléphone, si je veuxvalider la forme d'un numéro de téléphone, pour uneadresse e-mail, si je veux valider laforme d'une adresse e-mail. L'avantage,
00:59:13 :c'est que je pourrais réutiliser ces validateursdans plusieurs classes, puisquemes descripteurs sontséparésde la classe dans laquelle je l'utilise.Je peux très bien avoir une classe B maintenant,classe B,dans laquelle je pourraisavoir un x également,qui s'appelle number, et puiscette fois, qui fait une validation
00:59:35 :entre30 et 150,par exemple. Donc, c'est réutilisable.Il y a encore un petit souci, par contre.C'est qu'ici,pour l'instant,je supposeque ma variable s'appellex. Enfin, plutôt,
00:59:55 :ici, que ma variable à l'intérieurou la variable où je sauvegardela valeurs'appelle x.Et donc, j'ai un problème simaintenant je veux mettre un y ici,qui est aussi en nombre, et je veuxlui valider que la min valueici, elle est de 0,par exemple.
01:00:15 :Et queici, la max valueest de10.Si je fais ça,j'ai un souci.C'est interdit.Désolé, j'ai mon téléphonequi sonne, il n'aurait pas dû.
01:00:39 :Hop, je vais couper ça.Voilà.Alors, j'aurai une collision non,parce que les deux numbers,ils auront les deux à voirici, enregistrer une variable,un attributprivé x dansmon objet.
01:00:59 :Alors,une possibilité, c'est desauvegarder dans ledescripteur lui-même. Ça, c'est éventuellementune possibilité.Donc, plutôt que object.xje pourrais ici utiliserself.x et self.x
01:01:15 :et je sauvegardedans l'objet directement,mais comme cet objet, il estinstantié pourla classe,cet objet va être partagéentre toutes les instancesde la classe A.
01:01:31 :Donc, je ne peux pas le faire comme ça.Donc ici,quelque part, il fautcréer un moyende dire, ok,ici,ce nombre-làest associéà un objetqui s'appelle x.
01:01:51 :Et donc, je vais aller sauvegarderma valeur dans une variableoù j'en attribue icil'instance qui s'appellepar exemple underscore x.Dans la convention des pythonistes,underscoredésigne les variables privéespar convention.
01:02:09 :Pour le coup, ce que je voudraisfaire, c'est que quand j'affectel'instance de numberà y,j'aimerais pouvoir sauvegardercette valeur dans underscore y.Et donc, il y aun mécanisme qui permetà Pythonde reconnaître le nomde la variable, de l'attributauquel est affecténotre descripteur.
01:02:39 :Ce nom est reçu parune méthode, ici,qui s'appelle setName.Cette méthode,possède deux variables.Une s'appelle owner, qui varecevoir l'objetA qui est créé.
01:02:57 :Et le nomde la variableici,code.js instance.ynumber, cette méthodesetName va être appeléeet ce queon va recevoir dans ce cas-làc'est comme namela variable x.
01:03:17 :Donc, ici,je peuxsauvegarder en nom,par exemple, name.On peut même dire private name.Ici, name.Donc, si je sauvegardele nom,ce que je voudrais, c'est allerenregistrerun attribut dans cet objetqui s'appelleunderscore name.
01:03:43 :Et donc,qui reprend ça.Est-ce que vous savez,vous avez déjà entendu parler,est-ce que vous voyez comment allermettreà l'intérieur d'un objetcréer un attributdont je connais le nomsous forme d'une chaîne de caractère.
01:04:03 :Comment faire ?Ici, je ne peux bien sûr paslui indiquer ça,parce que ce underscore name n'existe pas.Comment allerlui mettre, par exemple,un underscorex à l'intérieur de cet objet ?
01:04:19 :Vous avez déjà entendu parlerdes méthodesgetAt,on fait des fonctionsici, getAt,et puis respectivement ici, setAt.Est-ce que vous avez déjàrencontré ces deux fonctionsde Python, par ailleurs, quisont des fonctionsnatives.
01:04:43 :Si vous allez dans la doc de Python,on a fait un entorah sur la docde Python il n'y a pas longtemps.On va sur la documentationde la biotech standard et on vadans les fonctions natives.
01:04:55 :Ici, dans les fonctions natives, vous avez deux fonctionsqui s'appellent setAt,ici, et getAt,qui est ici.getAt me permetde faire l'équivalent depar exemple ceci.
01:05:09 :Je retrouve mon truc.Si j'ai un objet,créer un objet,en OBS,je crée un objet.Je crée un objet.Vous allez mettreune valeur de 77sur un attributde cet objet,mais vous avez également la possibilitéde faire ceciavec la méthode setAt,ici, objet,et plutôt que de dire
01:05:55 :objet.x, vous allez simplementutiliser une chaîne de caractère xici, et lui dire que vous voulezdonner la valeur 77.C'est une manière d'aller définirun attribut sur un sujet,sur un objet, et lui donner une valeurquand le nomde l'attribut que vous voulez créer est disponiblesous la forme d'une chaîne de caractère.
01:06:15 :Et puis ici, plutôt qued'appeler obj.x,j'ai la possibilité de faire la chose équivalentequi est getAtgetAt objet puis du coup x sous formed'une chaîne de caractère.
01:06:29 :Alors je peux utiliser ces deux méthodesexactement pour ça ici.Je peux ici utilisergetAt pour dire aller chercher dansobj la méthodequi est appelée underscoreet puisle nom, alors icix ou y,donc le self.net
01:06:51 :Et puis, pareil pour setAt,ici je veux aller dans l'objetdans l'objetje veux aller chercherune méthodequi s'appellera underscoreet puis le nomque je définisdonc y ou xet puislui donner la nouvelle valeurici valueet du coupj'ai ici unevalidateurqui me permet
01:07:25 :d'aller valider tout ce que je veuxici x, yici self.yégal yet, alors déjà il fautque je lui donne deux valeurs, alors maintenant100ici et puis là on va lui donner 5ok, donc là on voitil repère quema valeurpour x est trop grande
01:07:49 :puisque je lui donne 100 et puis j'ai besoin d'une valeurentre 1 et 50alors mettons qu'on lui donne maintenant25on voit que c'est okça fonctionneet ici la deuxième valeury, je lui ai donné 5donc c'est bien entre 0 et 10, mais maintenantimaginons que je lui donne 11 pour le y
01:08:09 :et là, il repèrebien que le yje lui ai donné une valeurqui est hors de son domaine de validationdonc on voit que non seulementj'ai crééun descripteurqui me permet de faire de la validationdans plusieursclasses, mais dans la même classe je peuxréutiliser plusieurs fois ce validateur
01:08:33 :si j'ai des attributs qui aurontun nombre et des attributs d'instanceje peux au niveau de la classedéfinir ici un attributqui a le même nom queici mon attributd'instance, qui se va définiren lui donnant la valeur d'un descripteuret pour lequel je vais pouvoirdonner des critères
01:08:53 :de validation, minimum, maximumetc.mais ici, je pourrais très bienavoir un email et puis créerun descripteur qui s'appellemon emailcomment je devrais le faireexactement de la même manièreclasseemailune méthode getetc.
01:09:21 :on vaen geten geten set, en set nameet de la logique qui permettra de validerle nom de l'emailici pourvérifier que c'est bon, peut-être que j'ai pas besoind'en set icipeut-être que simplementen get suffitmais voilàvalider que cet emaila fait qu'une valeur
01:09:49 :possède bien une arrobasepar exempledonc ici j'aurais besoin effectivement d'en setpour sa emailself.emailégal emailon va faire une validation vraimentà deux balles ici, on va simplementgetet puis setself.obj
01:10:15 :pointvalueicion fait la même choseet puis icion fait la même chose, simplementon va aller voirque l'intégreur certifiepermet de gagner du temps dans un Montorac'est parfait, alors ici par exempleon donne une valeur d'erreurs'il n'y a pas d'arrobase à l'intérieurdonc ici
01:10:43 :si pour le coup j'ai monvalidateur d'email, silorsque je crée la classe, je donneici un Thierry100atexemple.comtypiquementici on va lui remettre une valeurcorrecteon voit que la valeur Thierryn'est pas reconnue comme une adresse email valideet donc j'ai un validateur
01:11:13 :d'email que je peux très bien avoir dans unebibliothèque de validationet puis sipour le coupje lui donne ici un emailqui est perçu comme valide, alors attention là je vérifievraiment l'email de manièretrès simple, on peutimaginer et vérifier la forme de l'email maiségalement ça ne garantit
01:11:33 :pas que l'email existeet voilà maintenant quand on lui passeun email correcton voit que chaque fois il appelle la méthode setici puisque j'ai misle petit print icidonc ça c'est une utilisationpar exemple pratiquededes descripteurset donc je vous encourageà aller dans la doc de Python
01:11:59 :de nouveau doc de Python racine dela doc, donc si vous allezà la racine de la doc icivous avez une sectionoù il y a les autoset dans ces autos vous avez le guidedes descripteurs et par exemplevous pouvez aller voir icipar exemple le mécanisme
01:12:17 :de propertyvous pouvez voir commentvous pourriez implémenter votre propre décorateurproperty, icije vous montre comment avec un descripteur vous pouvezcréer votre propre décorateurproperty qui fonctionne exactementcomme le décorateur propertyde Pythondonc ce qu'on voit c'est quele décorateur property de Pythonutilise exactement les mêmes mécanismes
01:12:41 :qu'on utilise avec une méthode get, une méthodeset, une méthode delete etune méthode set name pour le grosdu fonctionnement quiqui fait que c'estle property que vous connaissezpeut-être déjà et donc vous pouvezétudier le fonctionnementtoujours dans les fonctions nativesdonc dans la doc de Python
01:13:01 :les fonctions nativespropertyetle property que vous connaissezque vous avez peut-être déjà utilisési ce n'est pas le cas c'estpratiquement la fonctionque j'utilise le pluslorsque j'utilisedes classes et que je fais de la PO en Pythondonc n'hésitez pas à l'utilisermais ici vous voyez que
01:13:25 :en connaissant les descripteursvous pouvezfaire exactement la même choseet donc vous pouvez à ce stadecomprendre ce qui se passederrière la magiequi a l'air de se cacher derrièreces propertiespour la question qui a étéposée tout à l'heure au niveau des mécanismesà la fin de ce guide
01:13:47 :il y a vraiment, ce guide il commence simpleavec des exemples relativement simpleset il finit avecdes descriptions détailléesdes mécanismes sous-jacents en Pythondoncce guidesur les descripteurspeut convenir à ceux qui veulent justedémarrer et qui sont curieux de voircomment ça fonctionneet d'avoir un petit peu plus de texte autour
01:14:11 :de ce que je vous ai présenté aujourd'huimais également si vous avez envie d'allerfranchir en pas, d'aller un petit peu plus loindans la compréhension des mécanismesliés au fonctionnementdans les classes de Pythonles descripteurs sont au centrepourquoi ils sont au centre ?
01:14:27 :parce qu'on a vu la fonction propertyc'est un descripteur, mais les méthodeselles-mêmes, si je crée une méthodeicisi je crée une méthode, par exemplegetValuequel que soit le nom que je lui donneune méthodeest un descripteur égalementdonc en comprenant les descripteursvous comprenez ce que fait une méthode
01:14:49 :et dans le guide sur les descripteursvous pouvezeffectivementvoir en gros comment Pythondéfinit une méthodeça c'est grosso modoune classeécrite en Python quiémule le fonctionnementd'une méthode Pythondonc une méthode Python est un objetet c'est en particulierégalement quelque chose quifait appel à des descripteurs
01:15:19 :et c'estnotamment dans l'objet fonctiondonc une fonction en Pythonc'est un objet, donc si c'est un objet ça a une classeet cette classedéfinit un descripteurqui va êtreau centre du mécanismede fonctionnementdes méthodes en Pythonpeut-être que ici, volontairementj'en parle pas pour l'instant
01:15:43 :parce qu'ici on reste sur l'applicatifokmais ce mécanisme est vraimentau centre de tout quand il s'agitde parler de classede méthodede méthode d'instance, de méthodede classede méthode statiquede property en Pythonet comprendre les descripteursvous permet de passer un palierdans cette compréhension
01:16:09 :et ce palier vous pouvez le franchirà un niveau basiqueen suivantou en revisionnantce mentoratet à un niveau plus avancé en allant visionnerle guide des descripteurs duauto de Python. De manière générale
01:16:25 :la doc de Pythoncontient énormément de documentsque peu de monde lisedéjà en faisantle TOSAvous faites partie probablementdes personnes qui vont allerlire le plus de choses dans la doc de Pythonmais avant d'allersur Googleet de chercher des ressourcesla doc de Python
01:16:49 :regorge de ressourceset de tutoriels débutantset avancéset ici ça fait partie des mécanismesun peu plus avancés mais qui peuvent vous fairepasser un palier au niveau de la compréhensionVoilà, donc vous ne pouvez pas allerau-delà dans la matièremais n'hésitez pasà poser des questions si vous en avez
01:17:09 :Donc ce mentoratest enregistréil est disponibleen rediffusionje vais voir s'il y a encore des gens qui sont làil semble être le casdonc c'est déjà pas malje vais arrêterla présentationvous pouvezétudierces mécanismes en rediffusionvous pouvez aller dans la doc de Python
01:17:41 :donc je vous encourage à ça et n'hésitez passi vous avez des questionsje suis à votre dispositionMerci ThierryMerci ThierryBonne soiréeTrès belle soirée alorsà toutes et touset puis à tout bientôtMerci beaucoupBonne soiréeMerci ThierryMerciSous-titres réalisés par la communauté d'Amara.org
Aucune occurrence trouvée pour « ».
00:01:06
Introduction aux descripteurs
00:07:56
Comparaison avec les properties
00:10:42
Créer un descripteur intelligent : exemple du répertoire
00:42:07
Validation et cache avec descripteurs
01:11:55
Ressources de la documentation Python et conclusion