Vous avez spécifié que ces mots clés ont été implémentée en 3.10 Par ailleurs, estique cela peut poser problème si l'on reste sur une version antérieure pour les études supérieures et le travail ?
J'ai une question pas forcément en rapport avec la vidéo. Dans une class, on a des méthodes qui ont toutes la syntaxe suivante : __METHODE__ (il y a deux underscore de chaque côté mais youtube met en place le markdown...) J'aimerais savoir si c'est possible d'en créer soi-même et si cela change quelque chose comparé aux méthodes classiques. Merci pour tes explications très claires ^^
Ce sont des méthodes reservées aux fonctionnalités internes de Python, il ne faut donc pas essayer d'en créer soi-même. En soi c'est des méthodes classiques mais c'est simplement comment elles sont utilisées derrières par Python
La bibliothèque "typing" est une des incontournables de python ? Je vous vois beaucoup l'utiliser et j'aimerais savoir si c'est possible de faire la même chose mais en y faisant abstraction.
elle n'est pas incontournable mais elle propose un panel très large de types, classes et décorateurs très utiles pour les annotations de types ou ici pour définir plus explicitement le type de comportement attendu sur les classes et méthodes. De manière générale les objets de typing ne sont pas considérés par l'interpréteur de python mais sont utilisés par le type checkeur statique (ex. mypy), et permettent un code bien plus lisible et explicite globalement
Le module typing reste de la documentation personnalisée. Par exemple pour Final tu documentes juste le fait que tu ne veux pas qu'on réécrive ta méthode. Mais au lieu de le mettre dans un commentaire ou dans la doc de ta fonction ça affiche des trucs dans ton éditeur (ici un beau soulignage rouge si tu réécris la méthode). Mais ça ne changera jamais rien à la logique de ton code
Hello merci pour cette vidéo, c'est un sujet "tricky" ! J'ai vu que tu utilises beaucoup de typing dans tes vidéos, est-ce-que tu pourrais faire une vidéo dédiée, qui explique les meilleures pratiques, par exemple comment structurer son code pour éviter des erreurs de références circulaires quand on utilise du typing. Sinon super contenu, merci beaucoup Dave, tu es en train de devenir le Corey Schafer francophone ! Update : Je viens de découvrir ta vidéo dédiée au typing 🙏 !
j'ai un problème mon bot , sur discord , ne marche pas, pour les event (ex : boujour sa marche) mais dès que on utilise "!" il ne fait rie...... svp aide !
J'ai maté la vidéo en x2 en me disant que je connaissais déjà tout. J'ai eu l'agréable surprise de découvrir le groupe d'exceptions, le "from e" et le ".add_note" Merci et continue comme ça 😊
A mes yeux les classes ça permet de faire facilement ce qui est souvent difficile avec des fonctions en terme d'orga et de lisibilité. Même si je préfère de très loin la POO (à mes yeux bien plus naturel sur des projets) je pense que le style le plus complet et facile à lire ça doit être celui où les 2 sont utilisés et se complètent.
ca depend mais c vrai que dans le web on utilise plus souvent de fonction ou des script coté server apres pour certaine features qui ont besoin de methode et d'effectué des operation différente sur un objet dans ce cas se sera mieux une class un bete exemple pour gerer les differente operation avec la data base on va préferer crée une class database avec dans le constructor la connexion a la database et ainsi une fois la class instancier tu peux appeler toute tes methode pour crée tes tables, les modifier editer des rangée,... par exemple dans le cas de l'interaction avec une database sql j ai jamais vue aucun dev faire autrement qu'avec une class c'est pourquoi ca depend des cas mais si tu fais des systeme avancé un moment ou un autre tu aura besoin de créer des class pour mieux strucuturé et mieux auto documenté ton code
waah la gestion des erreurs python est bien plus poussée que ce que je connaissais ! Je savais utiliser les try-except-else-finally, je savais qu'on pouvait définir des noms d'erreurs personnalisés avec les classes, mais par contre je ne connaissais pas du tout ExceptionGroup (extrêmement pratique pour le coup), ni l'importance réelle de except ... as e: raise ... from e, merci pour ta vidéo c'est vrai que ces concepts sont assez chevelus et rarement abordés en profondeur ou même utilisés correctement
On va nuancer un peu des 2 côtés : -> La POO fonctionne différemment dans tous les langages. Tant dans les concepts que dans la philosophie. Donc effectivement l'argument "c'est juste de la POO" n'est pas valable puisque ce n'est pas comparable -> Effectivement en Python on ne met pas systématiquement en "privé" (et on ne met pas en privé avec un double underscore pitié) -> Ça ne veut pas dire qu'on ne doit jamais utiliser l'encapsulation non plus. Les propriétés et descripteurs ne sont pas là pour faire joli. -> Donc on "met en privé" s'il y a information sensible et SURTOUT s'il y a vérifications des valeurs
@@anyone3807 Merci beaucoup pour ton avis, mais j'avoue que je ne le partage pas du tout L'encapsulation est un concept fondamental de la POO, ça n'a pas vraiment de sens de penser que c'est individuel à chaque langage. Mettre un attribut en privé n'est pas non plus réservé à un langage de programmation, ça arrive lorsque comme tu l'as dis on a des vérifications de valeur à faire ou pour n'importe quelle autre raison où l'accès à cette donnée pourrait être mauvais. Quand tu commences à développer des projets assez gros, tu comprends que l'encapsulation peut vraiment aider à baisser le couplage et augmenter la cohésion de ton composant. Les propriétés sont une fonctionnalité exceptionnelle qui permettent de mettre en place de l'encapsulation sans avoir à utiliser une syntaxe de fonction. Comme tu l'as dis, elles ne sont pas là pour faire joli. Tu peux les utiliser pour créer des attributs dynamiques ou plus souvent pour encapsuler des données puisque ce sont des descripteurs avant tout J'ai regardé le lien que tu as envoyé par rapport aux simple et et doubles underscores pour les variables privées et à vrai dire ça ne change pas grand chose. On mets uniquement un underscore lorsque l'attribut est protégé et donc accessible uniquement dans la classe où se trouve l'attribut et dans ses filles. On en mets deux lorsqu'elle est vraiment privée c'est-à-dire accessible que dans la classe où se trouve l'attribut. C'est pour ça qu'on a du name mangling, pour qu'il n'y ait pas de problème si on veut définir un attribut avec le même nom dans la classe fille. J'aime beaucoup ce genre de commentaires parce que je pense que ça peut aider d'autres développeurs qui ont encore du mal avec la POO. Si tu souhaites un peu mieux comprendre l'orienté objets et surtout l'encapsulation du coup, je te conseille d'aller lire Object Thinking de David West et Elegant Objects de Yegor Bugayenko. Ce sont deux pépites qui permettent de comprendre beaucoup mieux la philosophie orientée objets et comment l'appliquer dans nos projets. Merci encore pour ton message ;) !
Je n'ai pas dit que l'encapsulation était indivuduel à chaque langage mais que la POO fonctionnait différemment. Les concepts et les bonnes pratiques ne sont pas du tout les mêmes. - Dans certains langages on a les interfaces, en Python y a pas - Dans certains langages on a l'héritage multiple et pas dans d'autres - Dans certains langages on a les attributs protégé et pas dans d'autres et quand il y est, leur fonctionnement n'est pas le même - Dans certains langages on a les traits et pas dans d'autres - Dans certains langages on utilise des design pattern qui sont contre-productifs dans d'autres... Après oui, il y a des concepts qu'on retrouve un peu partout mais selon les langages, la POO s'éloigne plus ou moins de UML. Il y a même certains langages ou la POO ne fonctionne pas avec des classes mais avec des prototypes. Un argument que je vois beaucoup trop souvent de la plupart des devs source de mauvaises pratiques "La POO (dans le sens traditionnel UML) prime sur les bonnes pratiques du langage". sauf que non, dans le cas où c'est faisable, c'est à cause de ça qu'on se retrouve par exemple avec des devs java qui font des getter et des setter partout qui ne font que renvoyer/modifier un attribut (en gros qui ne sert à rien) sans même utiliser les propriétés. Les propriétés sont un mécanisme mis en place par Python pour permettre de faire de l'encapsulation selon la philosophie du langage. Je ne comprends absolument pas quand tu dis "encapsulation sans fonction". Tu as une syntaxe alternative qui te permet de faire justement ceci sans decorateurs avec la fonction property. Non ce que tu dis est absolument faux, la notion d'attribut protégé n'existe pas en Python. Tu peux retourner la doc officielle et la PEP 8 dans tous les sens, absolument personne n'en parle. Ça c'est juste une idée reçue venue de développeurs d'un autre langage qui ont voulu recalquer leurs concepts en Python. Au contraire Python a toujours été contre les attributs protégés. Comme quoi même les "experts Python" n'ont même pas toutes les informations. Je t'ai mis la PEP 8 des conventions officielles de Python qui explique noir sur blanc que les attributs privés sont précédés d'un seul underscore et tu arrives encore à me contredire sur ce sujet en me disant que ca se fait avec un double, c'est une preuve que soit tu n'as pas lu ce que je t'ai envoyé, soit tu fais preuve de mauvaise foi puisque c'est un classique chez les développeurs de ne pas se remettre publiquement en question. Et non, la surcharge d'attribut n'a absolument aucun rapport avec les attributs privés. Je ne vais pas être hypocrite. Je déteste prendre de mon temps pour faire un gros pavé pour expliquer quelque chose à quelqu'un, donner des ressources dont certaines officielles pour appuyer mon argument et me faire contredire sur des points qui sont objectivement faux et recevoir des conseils derrière basé sur un sentiment de superiorité "eh tu t'es trompé mais c'est pas grave, lis ça et tu comprendras tout autant que moi". Vraiment désolé cependant pour mon ton virulent. Et je te remercie également pour le temps que tu as pris ainsi que pour les livres. Moi je vais m'arrêter là. Peut être que tu m'en voudras pas trop. Que tu sois d'accord avec moi ou non, j'ai dit tout ce que j'avais à dire et continuer ne serait qu'une perte de temps pour nous. Bonne continuation
Salut. Ta vidéo est plutôt cool et le format est vachement intéressant ☺. Je pense qu'elle peut vraiment aider un scripteur qui chercherait à se professionnaliser. Pour une fois que youtube me fait découvrir de la qualité ça fait plaisir. J'ai une sérieuse interrogation sur le titre par contre. je pense que le cas de figure présenté ne peut pas être réalisé de façon inconsciente par un développeur intermédiaire (dans sa définition la plus large, cursus validé et 2-5 ans d'expérience). L'absence de maitrise des designs pattern courants, et en particulier de la programmation orientée objet me semble tout à fait incompatible avec la qualification "Développeur intermédiaire python". C'est même incompatible avec la qualification "développeur" (y compris junior). Même pour un développeur web (RNCP37805), c'est une compétence explicitement requise. En bref, c'est une erreur de scripteur ou d'intégrateur, pas de développeur ! Mais j'pinaille et c'est vachement plus facile que de créer, alors m'écoute pas trop continue comme ça 😁
Mouais, Déjà je doute que les listes et dict soient des primitive Aussi, je ne vois pas le problème d'utiliser un dictionnaire pour représenter une ville ou une personne
Un dictionnaire en python est un mapping donc simplement une représentation des données sous forme clé-valeur, c'est simplement une structure de données. Ce n'est pas comme en TS où les dictionnaires peuvent être utilisés comme des objets
@@ilian572 ce n'est pas une faute en soit de représenter une ville via une structure. Mais disons que c'est généralement plus adapté d'avoir une class, dans la mesure où un système complexe comme une ville peut nécessiter l'ajout de fonctionnalités supplémentaires, ou devoir hériter de système parents (comme un système plus général qui s'appelle : ville) De même, l'allocation mémoire entre une struct et une class n'est pas la même, en tout cas en c++, je ne sais pas pour python. Représenter des floats, int, str : struct Représenter des objets complexes (voiture, avion, ville, personne...) : class
@@ilian572 absolument. Généralement, c'est lorsqu'il n'y a aucune méthode associée au code. Je pense que l'objectif de sa vidéo, est de pointer du doigt ceux qui oublie l'existence des class. Comme certains débutant qui utilisent des dict, et font du traitement de la donnée sur le dict. --> les classes sont faites pour ça. Mais tu as raison. De toute manière, une classe est un dictionnaire quand on creuse alors bon ...
Bonjour, Félicitations pour l'ensemble de tes contenus, présentation claire et pédagogique. Juste une remarque: à 11:25, tu expliques qu'il vaut mieux lever une erreur que renvoyer une valeur bizarre qu'il faudra traiter après coup, mais à 16:30, pour get_multiple_student_average(), tu fais exactement l'inverse: il serait nettement préférable de lever une erreur si aucun étudiant ne suit la matière, plutôt que de renvoyer 0 (la moyenne n'est pas 0, elle n'existe pas).
Pourquoi ne pas tout simplement créer une classe et accéder à ses attributs de manière traditionnelle ?? Je ne comprend pas ce qu’apporte ce concept appart risquer des Runtime exceptions en cas de type incompatibles.
Les classes en python sont plus lourdes que des dict, donc si tu veux simplement représenter des valeurs, sans avoir besoin d'ajouter des méthodes spécifique pour cette classe, ou avoir besoin des méthodes type __add__, __sub__ etc.. Tu préfères utiliser des typedDict. Aussi, comme c'est des dictionnaire ca peut etre plus facile à intégrer avec du code existant qui utilise déjà des dictionnaires, plutot que de tout changer pour ca fonctionne avec des classes
C'est exactement ça, ici le gros avantage des TypedDict est de pouvoir créer des structures de données simples qui sont basées sur les dictionnaires un peu comme les objets en TypeScript
Concernant l'utilité de Required, peut être qu'il faut le mettre en perspective avec le total=False, comme ça même si les autres clefs sont optionnelles celle marquée Required est quant à elle obligatoire
7:46 si tu définis total =false, les clefs sont toutes optionnelles, sauf celles ou tu indique required. Selon les cas cela peut être plus pratique que de rajouter des noterequired a presque tous les clefs
Très bonne vidéo comme à chaque fois, est-ce que tu compte aller sur les designs patterns au bout d'un moment ? (je pense que tu as pas mal de sujet avant d'arriver a du software engineering mais je prie pour que ça arrive plus tôt ^^)
À force de lire mes commentaires sur chacune de tes vidéos, tu vas sûrement me trouver répétitif, mais je sais pas comment tu fais pour choisir le sujet de la vidéo à chaque fois dans le mille d'une lacune ou d'un concept à côté duquel je suis passé jusque là. C'est incroyable ce que j'apprends avec toi, j'ai vraiment l'impression d'être en train de faire passer mes connaissances en python au next level, merci pour ce que tu fais
Franchement ça fait super plaisir de lire ce genre de commentaires ! C'est avec plaisir ! J'ai vraiment envie de créer un maximum de contenus pour expliquer les concepts les plus avancés de Python et de l'informatique en général donc j'espère que les prochaines vidéos pourront aussi t'aider ;)
Super clair, je connaissais pas du tout les TypedDicts ! Est-ce qu'il y a un tuto de prévu sur les tests unitaires ? S'il y a bien une chose que j'arrive pas à saisir c'est ça :/ Encore une fois, merci pour ces vidéos super claires :)
@@thuiop1 Je me demande donc quel est l'avantage des TypeDicts vs les dataclasses... Personnellement j'utilises des dataclasses et je ne vois pas d'inconvénient pour l'exemple montré.
très intéressant l'abstraction, je me demandais en lisant le code de certaines bibliothèques python ce que signifiait cette classe ABC qui était importée sur des classes avec des méthodes "vides", grâce à toi je comprends mieux ! Par contre en général ceux qui font ça mettent souvent un "return NotImplemented" ou "return NotImplementedError" plutôt que "pass" afin d'avoir une vraie erreur de l'interpréteur lorsque la méthode est appelée directement je suppose, j'ai l'impression que chez toi tu as une erreur de mypy mais que si tu lançait le code en appelant Animal.bruit() ça fonctionnerait et n'afficherait juste rien. D'ailleurs, c'est quoi fondamentalement la différence entre NotImplented et NotImplementedError ? Si quelqu'un peut me conseiller là dessus je suis preneur
Sur le plan de la pédagogie, je trouve ça un peu confusant. Comme je sense que tu aimes transmettre je vais prendre le temps de développer, mais je pense que ça peut aussi t'éclairer dans ton usage de la récursion. Tu représentes le problème comme une itération en décomposant les étapes du call stack (le fait de faire des print pour que l'apprenant voit où il en es est d'ailleurs très symptomatique de ça). C'est une façon classique d'enseigner la récursion mais je pense qu'elle va contre le paradigme et ne permet pas de gagner de la perspective. L'erreur que je vois tout le temps quand quelqu'un cherche à comprendre ou déboguer une fonction récursive, c'est de la dérouler dans sa tête. C'est une perte d'énergie, et je pense que cette pratique vient de cette technique d'enseignement et des habitudes de l'itération. Aussi, ça mène à des solutions récursives moins claires car trop impératives. Tu aurais pu rendre ton implémentation plus lisible par exemple en écrivant `if len(liste) == 0` ou `if not liste` (parce qu'une liste vide est falsy en python), et je vais expliquer pourquoi c'est plus lisible au delà de la cosmétique. Le principe de la récursivité, c'est d'implémenter le patron conceptuel "diviser pour régner". Ça se présente toujours de la même façon : "je ne sais pas résoudre X, mais je reconnais des sous-parties dans X que je sais résoudre en isolation et que je peux composer". Dans le cas de la somme d'une liste, en programmation fonctionnelle je ne peux pas itérer, parce que je ne peux pas maintenir un compteur mutable, par contre je peux additionner deux nombres et je peux extraire le premier élément et la queue d'une liste liée (le seul type de liste purement fonctionnel). C'est important de rappeler ces faits parce que autrement on trouve (à raison) arbitraire et inutilement compliqué d'utiliser la récursion pour faire une somme. La récursion résout toujours un problème, parfois purement récursif, d'autres fois simplement plus élégamment exprimé de façon récursive, mais il faut le nommer ce problème. Ce n'est pas un outil technique mais conceptuel. Donc, je peux décomposer le problème en deux cas : soit j'ai un cas trivial dont je connais la solution, c'est à dire la somme d'une liste vide (qui vaut 0), soit j'ai un cas problématique, c'est à dire la somme d'une liste non-vide, et là je dois me rapprocher du cas trivial, donc je vais en extraire un élément que je peux additionner. Reste à composer ces deux parties de solution en exploitant le fait qu'en programmation fonctionnelle on peut toujours substituer une expression par son résultat (parce qu'il n'y a pas d'effets secondaires) et c'est là que j'implémente l'appel récursif dans mon addition pour additionner le nombre que j'ai extrait, au résultat de l'appel récursif dont je sais qu'il sera 0 pour le cas de base, donc je retourne toujours un nombre. Du coup, pourquoi c'est pas bien de dérouler une fonction récursive dans sa tête ? Parce que la raison d'être de ce patron conceptuel c'est de ne pas avoir à le faire. On a juste besoin de penser au cas simple, à la façon de transformer le cas compliqué en cas simple, et à la façon dont les deux se composent. C'est purement déclaratif, pas impératif. Une fonction récursive non triviale est quasi impossible à dérouler dans sa tête (surtout quand il y a plus de 2 cas ou quand il y a du ping-pong entre plusieurs fonctions), et je ne compte plus les commentaires de développeurs frustrés qui pestent contre la récursion parce qu'ils ne savent pas lire du code récursif..
excellente introduction pour map, filter et reduce, j'utilise déjà map et filter quotidiennement mais reduce j'avais du mal à saisir la logique derrière. En les présentant de cette façon je me rends compte à quel point les 3 sont similaires
En fait reduce est fondamentalement différent, mais c'est peut-être un peu moins apparent en python parce que map ne retourne pas une liste quand tu lui donnes une liste, alors qu'il "devrait" (en tout cas s'il veut s'appeler "map"). Reduce est un catamorphisme, c'est à dire qu'il détruit la structure de départ pour te permettre d'en extraire les valeurs, alors que map te retourne la même structure avec les valeurs modifiées. Le hic quand on implémente reduce sur une collection (parce que c'est pas obligé) c'est qu'une collection a plusieurs valeurs, or tu ne peux pas retourner plusieurs valeurs à moins de les mettre dans une nouvelle structure ou de les résumer à une seule valeur. C'est donc ce qu'on fait quand on utilise reduce : Soit on définit un accumulateur initial qui va être la nouvelle structure que l'on remplit incrémentalement ; Soit on réduit les valeurs à une seule valeur. Raisonner de façon abstraite lorsqu'on utilise reduce est la seule façon de bien l'utiliser. C'est une abstraction très puissante quand tu la couples aux monoïdes et semi-groupes. Si tu l'interprètes comme une façon bizarre d'itérer, il vaut mieux simplement boucler
J'ai remarqué que mypy perdait régulièrement les pédales avec match/case. Le seul moyen de s'en sortir c'est d'utiliser des conditions avec isinstance. J'espère que ce sera réglé un jour. Si non c'est triste que ce ne soit pas une expression, mai bon voilà c'est python...
Super video tres informative. Par contre, maintenant entre les proprietes et/ou dataclass, ca serait super que tu combines cette video et celle sur les dataclass pour eventuellement expliquer si on peut combiner les 2 ou pas. J'avoue n'avoir aucune idee sur la question et peut etre meme que ma requete ne fait pas de sens.
Très bonne vidéo, dense en informations. Comment vous-êtes vous formé sur Python : simples tutos/vidéos ou cursus précis (fac) ? Et quelle durée approximative pour arriver à ce niveau ?
Merci beaucoup ! J'ai commencé l'informatique il y a 4-5 au lycée puis j'ai continué en fac d'informatique. La réalité est que je n'ai pas appris grand chose dans dans ces formations, la majorité de mon apprentissage a été dans les livres pour les concepts de développement de logiciels de haute qualité et les documentations officielles pour les langages de programmation et les librairies
Excellente vidéo qui montre très bien un cas concret d'application de la SRP, ça m'a vraiment aidé à mieux comprendre à quel point il ne faut pas avoir peur de définir une multitude de petites pièces de puzzle pour les assembler ensuite plutôt que de tout faire en bloc
Merci beaucoup ! On peut parfois se dire que c'est inutile de créer trop de petites pièces mais le plus souvent ça crée un code plus simple à comprendre et qui est surtout bien plus maintenable