Python de premier niveau : Devenez un expert Python | ArjanCodes | Skillshare
Recherche

Vitesse de lecture


1.0x


  • 0.5x
  • 0.75x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Python de premier niveau : Devenez un expert Python

teacher avatar ArjanCodes, Become a Better Software Developer

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Aperçu du cours : ce que vous allez apprendre

      1:02

    • 2.

      Comment les différentes langues de programmation traitent avec les types

      7:25

    • 3.

      Annotations de type dans Python : de base à avancé

      4:21

    • 4.

      Duck Typing avec les cours de protocole

      5:28

    • 5.

      Comment les bases de données vous aident à écrire de meilleurs cours

      10:56

    • 6.

      Libérer le pouvoir des propriétés de la classe

      4:44

    • 7.

      Quelle est la différence entre str et repr ?

      2:33

    • 8.

      Comment améliorer les performances de l'accès aux membres du cours

      3:17

    • 9.

      Callables et fonctions de commande plus élevé

      5:29

    • 10.

      Application de fonction partielle

      3:10

    • 11.

      Propriétés en cache

      2:01

    • 12.

      Expédition unique

      2:58

    • 13.

      Qu'est-ce que la programmation simultanée ?

      4:07

    • 14.

      Async, attendez et réunissez

      5:21

    • 15.

      Comment transformer le code non concurrentiel en code simultané

      3:46

    • 16.

      Iterators and itables : les bases

      5:44

    • 17.

      Utiliser les itérateurs pour présenter l'abstraction

      1:20

    • 18.

      Itertools : une Algebra de nouvel éditeur

      7:27

    • 19.

      Générateurs aka Lazy Interators

      1:39

    • 20.

      Fonctions du générateur, rendement et retour

      2:18

    • 21.

      Expressions de générateur

      1:42

    • 22.

      Générateurs et concurrency

      3:39

    • 23.

      Qu'est-ce qu'un gestionnaire de contexte ?

      1:32

    • 24.

      Cours de gestionnaire de contexte

      2:33

    • 25.

      Context Manager Decorator (beaucoup plus facile ! )

      1:10

    • 26.

      Gestionnaires de contexte et concurrence

      1:58

    • 27.

      Conclusion

      0:30

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

718

apprenants

2

projets

À propos de ce cours

Voulez-vous développer votre connaissance de Python et faire passer vos compétences en codage au niveau supérieur ? Si oui, ce cours est fait pour vous ! Ce cours vous permettra de mieux comprendre Python et de rédiger un code beaucoup plus rapide.

Ce cours est conçu et contient les sujets qui, selon moi, seront les plus bénéfiques pour vous si vous voulez devenir plus qualifié chez Python.

C'est ce que vous allez apprendre :

  • Quelles sont les annotations de type et pourquoi il est important de les utiliser
  • Utilisation avancée des cours, y compris les bases de données, les propriétés et plus
  • Programmation fonctionnelle avancée utilisant les fonctions de lambda, application de fonction partielle et plus
  • Techniques de programmation simultanées pour optimiser comment votre code interagit avec les API
  • Logique de contrôle avancée utilisant les itérateurs et les générateurs
  • Et plus encore !

Que vous utilisiez principalement Python pour traiter et analyser les données ou que vous utilisez Python pour créer des applications logicielles complexes telles que les API , vous allez vraiment profiter de ce cours et devenir un véritable expert Python.

Donc, si vous êtes prêt - dive !

Rencontrez votre enseignant·e

Teacher Profile Image

ArjanCodes

Become a Better Software Developer

Enseignant·e

Hi there!

I'm Arjan - I'm a YouTuber, entrepreneur and online teacher. I've completed both a Master and PhD in Computer Science and I've been a university teacher for over 20 years, I've launched several and designed and built complete software products from scratch.

On my YouTube channel ArjanCodes I teach software design, development and testing - specifically in Python. A lot of people are learning how to code in Python. They often start with writi... Voir le profil complet

Level: Intermediate

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Introduction: Bonjour, je suis désolé, je suis le bienvenu dans ce cours qui enseigne la programmation Python de niveau intermédiaire à avancé. Il s'agit d'un cours organisé. Il ne s'agit pas d'une liste complète de toutes les fonctionnalités avancées possibles disponibles dans Python. Il contient les éléments qui, selon moi , vous seront les plus utiles si vous souhaitez passer à étape suivante de votre carrière dans le développement de logiciels. Ce cours s'adresse à vous si vous avez une formation en Python, mais que vous souhaitez en savoir un peu plus sur les fonctionnalités avancées proposées par le langage. Je vais donc parler de choses comme les indications de type, le code simultané, classes de protocoles, les itérateurs, les générateurs et quelques autres choses encore. Vous pouvez trouver tous les exemples de code utilisés dans le cours, dans l'onglet Projets et ressources. Et il y a aussi un petit projet amusant dans lequel vous pourrez vous lancer à la fin. Si vous aimez ce cours, vous aimerez peut-être aussi ma chaîne YouTube ou Young Colts, youtube.com, Slash Iron Codes. J'y ai principalement parlé de la conception de logiciels plusieurs modes de contenu Python. Alors jetez-y un coup d'œil. J'espère que vous avez apprécié le cours car vous êtes prêt. Plongeons-nous dedans. 2. Type Annotations 1/3: Je vais commencer ce cours en parlant des systèmes de types. De nombreux langages de programmation ont des types intégrés leur syntaxe et il existe différentes manières d' examiner les systèmes de types. Et je veux parler de quelques-unes d'entre elles aujourd'hui et de la façon dont cela se rapporte à la façon dont les types de problèmes sont traités en Python. La première est donc que nous avons statique par rapport à des systèmes de type dynamique. Et cette distinction concerne le moment où les informations de type sont acquises, que se passerait-il de manière statique ? Cela signifie que cela se produit au moment de la compilation ou de l'interprétation lorsqu'il est dynamique, cela signifie que les types sont déterminés lors de l'exécution. Une autre distinction dont vous avez peut-être entendu parler est la frappe forte par rapport à la frappe faible. Et il s'agit plutôt de savoir à quel point strict de nouer des liens de manière constante. Donc, par exemple convertit-il automatiquement les entiers en chaînes de caractères ou inversement ? Il n'existe pas de définition claire de ce qu'est exactement un système de saisie fort par rapport à un système de saisie faible. C'est pourquoi nous examinons généralement d'autres moyens de distinguer les systèmes de types, dont je parlerai dans une minute. Chaque langage de programmation aborde les types différemment. Par exemple, Java est typé statiquement. Cela signifie donc que si vous déclarez une variable de type chaîne et une chaîne, puis que vous essayez de lui attribuer un numéro. Ce n'est pas autorisé. Et la raison pour laquelle ce n' est pas autorisé est que nous avons défini au moment de la compilation que la variable serait de type chaîne, donc nous ne pouvons plus la modifier. Python, quant à lui, est un conduit dynamique Il est donc parfaitement possible de définir une variable et de lui donner une valeur de chaîne. Ensuite, nous lui attribuons une valeur d'un type différent. Fondamentalement, le type n'est pas associé à la variable, il est associé à la valeur i. programme Python très simple ici. Donc, si je définis une variable x et que j'attribue une chaîne, et comme Python est typé dynamiquement, je peux simplement lui attribuer une valeur de différents types, dans ce cas un entier, et c'est très bien. Ce n'est absolument pas un problème. En Java, cela entraînerait bien sûr une erreur. Maintenant, même si Python est typé dynamiquement, il est également assez strict. On pourrait même dire que c'est fortement dactylographié si nous avions une définition pour cela. Donc, par exemple ce que je peux faire, c'est que si nous avons la même variable X, nous pouvons faire bonjour plus cinq. Parce que si j'essayais de l'exécuter, vous verrez que vous obtiendrez une erreur indiquant que, hé, nous ne pouvons que concaténer des chaînes et non des entiers. Cela signifie donc que Python ne convertit pas automatiquement ce nombre cinq en une chaîne de cinq. Bien entendu, je peux le faire de manière explicite. Donc, quand je lance à nouveau le programme, vous voyez maintenant que cela ne posera aucun problème, car annuler la conversion de type moi-même est différent d'un langage comme JavaScript, qui vous permet de faire hello plus five. Ensuite, je vais simplement convertir automatiquement le nombre en chaîne. Et c'est également logique du point de vue de JavaScript, car ce que JavaScript est, bien entendu, le langage du Web. Et nous voulons nous assurer que le client montre toujours au moins quelque chose de raisonnable. JavaScript fait donc de son mieux pour faire tout ce qu'il peut avec les valeurs qu'il obtient. fonctionne pas toujours, mais cela signifie que même si une page Web contient des erreurs, elle peut toujours afficher quelque chose de significatif. Quelles sont les autres manières d' examiner les systèmes de types, alors que l'un d'eux est manifeste par rapport à un système inféré, manifeste signifie que vous devez spécifier explicitement le type de variable, par exemple C ou Java ont un typage manifeste, nous devons spécifier quel est le type. Déduit. La saisie signifie que le type de la variable va être déduit de la valeur. Et c'est exactement ce qui se passe en Python. Donc, sur Python, nous n'avons pas besoin d' indiquer que dans ce cas, x est une chaîne et rien d'autre. Pourtant, une autre façon de considérer les systèmes types est nominale par rapport à la structure. Nominal signifie que pour comparer si les types correspondent, le système de types examine les noms dans leur intégralité. Donc, si nous avons des choses qui sont des chaînes, elles sont toutes les deux du même type. Si nous avons deux choses qui appartiennent à la même classe ou que les classes sont également de même type, les types correspondent. C'est nominal. Structurel signifie que nous allons examiner la structure des objets afin de comparer si ces types correspondent. Ainsi, par exemple, si nous avons un objet qui possède une propriété x, alors les types correspondent à ceux d'un autre objet si l'objet possède également la même propriété x. Il faut donc vraiment regarder la structure de l'objet par rapport au nom de l'objet. Alors, dans ce cas, que possède Python ? Eh bien, ce n'est pas vraiment du typage structurel, mais c'est un peu similaire. C'est ce que l'on appelle le Duck Typing. La dactylographie en forme de canard est comme une structure renforcée, mais ce n'est pas exactement la même chose. Le typage structurel est un système de type statique qui compare les structures des objets lorsque vous compilez le code. Doctype est dynamique, mais il ne prend en compte que les parties qui comptent. Nous avons donc une certaine partie de l'objet à laquelle vous accédez lors de l'exécution. Disons que vous avez un objet avec une propriété x et une propriété pourquoi ? Et au moment de l'exécution, vous n' accédez à la propriété X que si les types correspondent si l'objet possède cette propriété et que nous ne l' examinons pas. Pourquoi, même s'il fait peut-être partie du type statique, le typage en forme de canard est en fait ce que Python utilise. Il examine donc simplement les pièces nécessaires pendant l'exécution. Correspondre. Python est prêt à fonctionner. J'ai ici un exemple qui montre comment fonctionne la dactylographie en forme de canard. J'ai donc quelques variables ici, ma chaîne ou ma liste, mon dictionnaire. Et bien qu'ils aient chacun des valeurs, vous voyez, nous avons une fonction de longueur qui peut imprimer la longueur de ces éléments. Ce n'est donc pas une 11e année car elle comporte 11 caractères. Cela s'appelle quatre parce qu' il y a quatre éléments dans la liste et cela va en imprimer trois. Et la façon dont cela fonctionne est que la fonction de longueur attend un objet. Vous pouvez déjà le voir ici en taille de caractères. Et cela signifie que cet objet doit être associé à une méthode Lynn Dunder. Et c'est le cas pour les chaînes, les listes, les dictionnaires. Donc, si je l'exécute, vous verrez qu'il n'y a aucun problème à exécuter ce code et à simplement imprimer ce que je voulais imprimer. Donc, ce qui se passe, ce sont les dictionnaires, les listes et les chaînes de caractères. Bien sûr, ce sont des types d'objets très différents, n'est-ce pas ? Mais Duck Typage les accepte comme arguments de la fonction length car la seule chose qui est nécessaire ici ou à laquelle on accède est la méthode length dunder. Donc, tant que c'est leur type de canard, Python est prêt à fonctionner et qu'il l'accepte, même si ce type ne correspond pas exactement sur le plan structurel car une chaîne n'est pas une liste et la liste n'est pas un dictionnaire. Mais dans un canard, le système de saisie fonctionne sans problème. Vous pouvez même aller plus loin, par exemple ici, si le livre de classe qui n'a pas d'initialiseur un auteur, un titre et des pages. Et j'ai défini ici la méthode de longueur moi-même, qui renvoie simplement le nombre de pages. Ensuite, j'imprime en appelant la fonction de longueur sur un objet de livre. C'est ce que vous voyez ici. Et puis, vous voyez que lorsque je lance ceci, vous obtenez ceci en conséquence. Donc, dans ce cas, cela fonctionne exactement de la même manière. La seule chose dont la fonction de longueur besoin est un objet de type size. Cela signifie qu' il devrait une méthode de don allégé, ce qui permet à cette classe de se contenter de la moitié. Ce code s'exécute donc sans problème car c'est ainsi que fonctionne Duck Typage. 3. Type Annotations 2/3: Avec Python, vous n'avez pas à spécifier explicitement de types lorsque vous écrivez un objectif. C'est une bonne idée de le faire, car cela vous aidera à rendre votre code plus facile à lire. Et c'est en fait très facile à faire. Par exemple, nous avons ici une chaîne qui est HelloWorld, mais vous pouvez en fait indiquer à l'aide d'indices de type ou d' un type de notation quel est le type de cette variable particulière. Et vous le faites simplement en écrivant une colonne puis vous tapez le type, vous tapez le type ici. Nous pouvons faire la même chose. Il s'agit donc d'une liste d'entiers. Je vais donc écrire une liste d'entiers. Et si vous avez un type générique comme celui-ci, vous pouvez utiliser les crochets pour taper avec le bouton droit de la souris derrière celui-ci. Et pour le dictionnaire, c'est très similaire. Nous avons donc un dict et le premier, le type de clé est une chaîne, n'est-ce pas ? Nous avons 12,3, ce sont des chaînes et ce que cela indique vers la valeur qui est un entier. Nous avons donc ici le type de dictionnaire, ailleurs, pour utiliser ce type de type. Et je vais vous dire que vous avez besoin de Python 3.9 ou plus récent. Sinon, vous devrez écrire en tapant import, dicter avec une majuscule, puis vous pourrez l'utiliser. Mais si vous utilisez une version récente de Python, vous pouvez simplement écrire ceci. C'est beaucoup plus rapide. C'est ainsi que vous spécifiez les types. Bien entendu, la classe est aussi un type. Je peux écrire quelque chose comme ça, être un sous-type de livre. Et ça va être un livre. Ensuite, nous pouvons lui transmettre certaines valeurs. Quelque chose comme ça. C'est ainsi que vous ajoutez des indices de type lorsque vous déclarez des variables. Maintenant, ce n'est pas très utile car lorsque vous regardez la ligne de code, vous pouvez déjà voir que c'est un livre. Alors pourquoi devrions-nous écrire cela, n'est-ce pas ? Ce n'est pas vraiment nécessaire, mais c'est vraiment utile si vous avez des fonctions ou des méthodes et que vous souhaitez spécifier des indices de type pour les arguments. C'est en fait ce que vous voyez ici. Nous voyons donc que nous avons un auteur de type chaîne. Nous avons un titre de type chaîne et nous avons des pages de type entier. C'est très utile car lorsque nous appelons l'initialiseur de livres ici, vous pouvez voir que j'utilise du code VS dans ce cas. Je reçois donc déjà les informations de type dans l'en-tête. Maintenant, je sais exactement ce que je dois fournir. Cet auteur est censé être une chaîne et vital est censé l'être également. Et met en page un intérieur. Vous verrez cela comme un type de retour ici. L'initialiseur de livres ne renvoie donc rien, et c'est correct. n'y a pas de déclaration de retour ici. Vous pouvez également l'écrire explicitement si vous le souhaitez, comme ça. Il renvoie donc aucun et une longueur. Si vous regardez cela, cela renvoie un entier. Nous pouvons donc également le spécifier explicitement. Une chose que vous pourriez vous demander est ce qui se passe si nous spécifions un type incorrect, par exemple, nous avons ici une variable de type chaîne, n'est-ce pas ? Et nous attribuons la chaîne, donc tout est correct. Mais que se passe-t-il si je transforme cela en un entier, par exemple, ce n'est clairement pas un entier, n'est-ce pas ? Donc, si nous exécutons cela, vous voyez que le code s'exécute totalement sans aucun problème, même si le type est complètement erroné. C'est pourquoi Python ne prend pas en compte ces types lorsqu'il exécute réellement le programme. Ils sont là uniquement pour nous aider, en tant que développeurs, à comprendre où se situent les problèmes dans notre programme. Vous voyez, nous n'avons même pas d' erreur ici et c'est là que les paramètres de VS Code peuvent nous aider à spécifier la rigueur avec laquelle nous voulons que notre système de vérification de type soit ouvert dans notre IDE. Maintenant, les paramètres de l'espace de travail dans VS Code et Dairy indiquent qu' un moule de vérification du type de points Python Dot Analysis est désactivé. Vous pouvez donc modifier cette valeur pour déterminer dans quelle mesure la vérification de type doit être stricte. Et il y a essentiellement trois options. Il y a Off basic et Stricter. Permettez-moi donc de le modifier en strict. Comme ça. Revenons maintenant à mon dossier et osons voir, hé, maintenant nous avons un problème. Vous voyez, ma chaîne est un entier, mais nous lui attribuons une chaîne. Et vous voyez également que nous obtenons une erreur d' incompatibilité fournie par les pilotes, qui est la surface du langage Python de VSCode. Permettez-moi donc de le remplacer par une chaîne ou vous, d'ailleurs, vous le verrez également ici. C'est ma chaîne qui est un entier. Je vois qu'ici, nous avons également un problème selon lequel un int peut être attribué car il n'est pas hors type. Size in n'a pas longueur (méthode dunder). Remettons donc cela en chaîne et nous verrons ensuite que le problème a été résolu. 4. Duck Typing avec les cours de protocole: Un type assez spécifique à Python dont je veux parler avec vous, et c'est la classe de protocole. Nous avons donc vu dans l'autre exemple que nous pouvons avoir de la classe. Et la classe est, bien sûr, un type. Mais ce qui arrive souvent, c'est que vous utilisez des classes et des objets d' un type particulier partout dans votre code, n'est-ce pas ? Voici donc un exemple où nous avons une classe appelée clients de messagerie ou disons qu' il s'agit d'un système d' envoi de courrier électronique. Et vous voyez, ce qui se passe ici, c'est que nous avons l'initialiseur qui obtient un tas d' informations comme les identifiants , les mots de passe, etc. Mais à l'intérieur de l'initialiseur, nous créons un serveur SMTP. Nous avons ensuite essayé d'obtenir l' hôte et le port à partir de l'objet serveur SMTP que nous venions de créer. Ensuite, nous faisons certaines choses, comme vérifier le nom d'utilisateur et le mot de passe, stocker ces deux adresses , etc. Ensuite, nous avons quelques méthodes comme se connecter au serveur, quitter le serveur et envoyer un message, envoyer un e-mail via cet internaute avec des éléments utiles comme l' ajout systématique des deux adresses , etc. Nous avons donc beaucoup de types ici. Vous voyez que nous avons ici les types de retour qui sont pour la plupart non. Nous utilisons également d'autres types d'annotations de type ici, par exemple, cela signifie que la connexion peut être une chaîne ou qu'elle peut être connue. C'est donc ce que l'on appelle également la syntaxe de type union. Cela signifie que vous pouvez combiner plusieurs types et qu'à un type ou par défaut, nous lui attribuons la valeur none. Vous voyez également que nous nous appuyons ici sur le type SMTP, qui provient de SMTP lib, n'est-ce pas ? Ce n'est pas un problème en soi, mais cela signifie qu'il n'y a aucune dépendance entre vos clients de messagerie et une classe SMTP très spécifique. Si vous souhaitez utiliser une bibliothèque pour cela, vous devez accéder à l'implémentation de la classe et corriger les références au SMTP, puis supprimer cette importation. Une autre méthode consiste à utiliser des protocoles. Et avec le protocole, ce que vous faites, c'est une très belle extension du mécanisme de saisie Duck. En Python avec protocole, vous spécifiez la structure de l'objet. C'est donc la partie structurelle de la dactylographie en forme de canard et ce à quoi vous vous attendez. Et puis le système de typage Duck de Python va correspondre à cela au moment de l'exécution. J'ai donc ici un autre exemple où j'ai utilisé ce mécanisme. Et c'est exactement la même classe. Nous avons donc à nouveau ici le client de messagerie, mais vous voyez maintenant qu'il y a une autre classe qui est écrite au-dessus et qui s' appelle Where are we ? Serveur de messagerie ? Un serveur de messagerie est une classe de protocole. Vous voyez que nous l'avons importé à partir de la saisie. Et puis il y a quelques propriétés et méthodes que j'ai définies. Il y a donc l'hôte et les flèches pour connecter les méthodes. Ce sont donc les méthodes standard qui constituent également l'essence de la classe de serveur B. Mais maintenant, nous transmettons aux clients de messagerie une instance de ce serveur SMTP, puis nous l'utilisons simplement. Et ce qui est bien, c'est que comme nous fournissons désormais simplement le protocole en tant que type, nous pouvons utiliser le serveur SMTP comme nous le faisions auparavant. Il suffit de le créer en dehors du client de messagerie. C'est ce qu'on appelle l'injection de dépendance, d'ailleurs. Et si nous voulons le remplacer par autre chose, par exemple, nous voulons utiliser un autre serveur SMTP ou peut-être utiliser un faux serveur SMTP afin pouvoir écrire des tests logiciels pour cette classe. Eh bien, alors nous pouvons simplement fournir cela. Et tant que la classe que nous fournissons, l'objet qui la fournira est conforme à ce protocole. Donc, tant qu'il possède ces méthodes et que doctype y correspond, nous pouvons l'utiliser en combinaison avec un client de messagerie. Et nous avons également perdu l'importation très spécifique ici depuis la bibliothèque SMTP, car maintenant nous nous appuyons simplement sur un protocole. Le protocole vous permet donc d' introduire une certaine abstraction dans votre code afin que vous n'ayez pas à inquiéter d'avoir de nombreux couplages, de nombreuses dépendances directes avec des bibliothèques de bas niveau, des pantalons serrés, comme je viens de vous le montrer , un outil vraiment utile pour améliorer la lisibilité de votre code qui peut être bibliothèques de bas niveau, des pantalons serrés, comme je viens de vous le montrer, un outil vraiment utile pour améliorer la lisibilité de votre code qui peut être utile si vous travaillez en équipe sur ce code ou si vous écrivez le code, puis quelques mois plus tard, vous y revenez et vous essayez de comprendre ce qui se passe et ce que vous êtes censé transmettre comme arguments à une fonction ou quelque chose comme ça. Les conseils de saisie sont très utiles pour clarifier cela et vous assurer que vous commettez moins d' erreurs en tant que développeur. Par exemple, voici une fonction de calcul de statistiques qui obtient des arguments. En fait, nous n'avons aucune idée, si vous regardez les dysfonctionnements gérés, de ce que nous sommes censés en faire Il y a des utilisateurs, des plantes et des produits, mais quels sont ces éléments ? S'agit-il de dictionnaires ou de listes ? Est-ce une cellule vers un numéro ? Nous ne le savons tout simplement pas. Si vous fournissez des indices de saisie. C'est beaucoup plus facile à voir. Nous pouvons immédiatement voir ce que nous devons fournir et le vérificateur de type intégré aux pylônes VSCode. Mais d'autres éditeurs ont également un correcteur de type comme celui-ci. Cela vous aide à comprendre où se trouvent les flèches et les résoudre avant même de devoir exécuter votre programme pour le savoir. Ainsi, les caractères contribuent à la lisibilité de votre code et vous aident également à détecter les erreurs plus tôt dans le processus de développement Les mains de saisie indiennes vous feront gagner beaucoup de temps. Je vous recommande donc vivement de commencer à les utiliser davantage si vous ne l'avez pas déjà fait. Ainsi s'achève cette leçon sur les indices de frappe. Dans la prochaine leçon, je vais approfondir les classes et vous montrer quelques choses très puissantes que vous pouvez faire avec elles en Python. 5. Cours de premier niveau 1/4: Dans cette leçon, je vais parler des classes et je vais vous montrer différentes choses que vous pouvez faire avec elles en Python. J'ai donc ici un exemple très simple. C'est une personne de classe, rien de spécial. verre presque vide a juste un initialiseur et reçoit un nom et une adresse. Comme vous pouvez le voir, ce sont des cordes. J'utilise des indices de frappe ici. Je devrais probablement ajouter, puisque l'initialiseur ne renvoie rien. Et puis j'utilise une fonction de génération d'identifiant. Vous pouvez voir cette fonctionnalité ici pour générer une sorte d'identifiant. Vous pouvez donc imaginer cela comme une base de données simplifiée. Ensuite, nous avons un nom et une adresse, et nous avons également une liste vide d'adresses e-mail. Voici donc le cours personnel, Basic. Et puis j'ai la fonction principale où je crée une personne avec un nom et une adresse, puis j'imprime cette personne. Donc, lorsque j'exécuterai ce code, voici ce que nous allons obtenir des résultats. Je suis donc en train d'imprimer un objet personnel. Vous pouvez le voir ici. Maintenant, ce n'est pas une information très utile, non ? Parce que nous obtenons simplement une adresse mémoire. Nous n'avons aucune idée de ce qui est réellement contenu dans l'objet Person, ce serait bien si nous pouvions réellement le voir. Et bien sûr, c'est possible en Python. Pour ce faire, vous pouvez principalement ajouter une méthode STR ou wrapper dunder. J'en parlerai davantage dans une minute. Mais dans l'ensemble, il existe une manière différente de définir les classes en Python. Dans l'ensemble, c'est un peu plus simple. Je me sens un peu plus facile à lire et c'est en utilisant des classes de données. Mais on pourrait dire que les classes de données sont vraiment plus orientées vers les classes orientées vers les données, n'est-ce pas ? Des points de données structurés, des vecteurs, etc. Au lieu d'un bouton d'une surface de chaussée ou d'une autre classe axée sur le comportement. Mais il ajoute de nombreux mécanismes pratiques, tels qu'un moyen beaucoup plus simple de définir des attributs. Vous pouvez les comparer beaucoup plus facilement. Vous pouvez les imprimer beaucoup plus facilement. Ces éléments sont donc utiles pour presque tous les types de cours. Comment transformer une personne en classe de données ? C'est en fait très simple. Donc, ce que je vais faire, c'est à partir des classes de données, je vais importer la classe de données, qui est le type que nous allons utiliser ici. Et puis, au lieu de définir une personne de cette manière, nous allons écrire une classe de données au-dessus. Et maintenant, ce que je peux faire, c'est spécifier les variables d'instance ici. Nous avons donc un nom, qui est une chaîne, et nous avons une adresse, qui est également le printemps. Et nous allons avoir une liste d'adresses e-mail. C'est une liste de chaînes, non ? Et la carte d'identité. Nous pouvons également le faire, je vais vous montrer comment le faire dans une minute. Mais si je supprime cela, vous pouvez voir qu' il est beaucoup plus facile de comprendre ce qu'est réellement une personne car nous pouvons simplement regarder haut et nous voyons immédiatement les noms des variables d'instance et leurs types. C'est pourquoi les classes de données sont vraiment utiles. Et j'y reviendrai dans une minute. Permettez-moi simplement de faire un commentaire. Mais maintenant, si je crée une personne de cette façon, cela se passe exactement de la même manière. Les classes de données génèrent donc en fait un initialiseur basé sur les valeurs de ces variables d' instance. Quand je l'exécute, vous pouvez voir qu'il imprime maintenant la personne. Mais vous voyez également que cette classe de données a déjà résolu ce problème si vous imprimez l'objet qui va imprimer quelque chose de significatif, et elle le fait en implémentant les méthodes wrapper dunder. J'en parlerai davantage dans une minute également. Alors, comment ajouter ces autres éléments à la classe de données ? Bien sûr, nous avons l' ID, qui est une chaîne, mais nous aimerions maintenant lui attribuer une valeur générée par cette fonction. Pour ce faire, nous devons utiliser la fonction de champ qui se trouve également dans les classes de données. Et ce que je fais ici, c'est que l'identifiant est égal à un champ et que la fabrique par défaut, c'est-à-dire que la fonction qui crée la valeur pour nous, sera generate ID. Maintenant, ce qui se passe, c'est que pour calculer cette valeur, la classe de données va appeler cette fonction pour la calculer. Et comme cette valeur a désormais une valeur par défaut, nous devons la mettre ci-dessous. Les autres cellules n' ont pas de valeur par défaut. Alors on y va. Maintenant, quand je l'exécuterai à nouveau, vous verrez que ma personne a maintenant un nom, une adresse, mais maintenant elle a aussi un identifiant qui a été généré en appelant la fonction generate ID. Vous pouvez également simplement fournir une valeur par défaut, par exemple supposons que nous ayons ici une variable d'instance active qui est une valeur booléenne. Et la valeur par défaut sera définie sur true. Désormais, une personne est active par défaut. Et vous voyez qu'il est désormais également inclus dans l' objet Person, ici même. Que pouvons-nous faire d'autre maintenant ? Eh bien, nous avons également les adresses e-mail répertoriées ici, alors ajoutons-les également. Et puis ajoutons également une valeur par défaut ici. Maintenant, vous pourriez être tenté d'écrire ceci. Ce n'est pas une bonne idée car la façon dont Python fonctionne est que cette valeur est en fait générée une seule fois au moment de l'interprétation. Donc, si vous l'attribuez comme valeur par défaut et c'est la même raison pour laquelle vous ne devriez pas attribuer de liste vide comme valeur par défaut dans les fonctions. Vous pourriez avoir un comportement inattendu, car toutes ces listes vides font essentiellement référence au même objet , ce que vous ne voulez pas. Donc, vous pouvez également définir un champ ici et simplement dire que la valeur par défaut, cette usine par défaut, sera l'initialiseur de la liste, comme ceci. Désormais, chaque personne aura également une liste d'adresses e-mail qui par défaut, sera vide. D'autres choses que vous pouvez faire avec des classes de données qui sont vraiment intéressantes. Eh bien, la première est que, comme nous l'avons vu, cela génère l'initialiseur. Nous avons donc ici une personne. Il a donc un nom, une adresse, identifiant, une adresse active et une liste d'adresses e-mail. Mais peut-être ne voulez-vous pas que l'identifiant soit là, vous voulez qu'il soit toujours généré. Ce qui est logique, non ? Nous ne le savions pas, nous ne voulons pas spécifier ces identifiants de manière explicite. Nous voulons qu'il soit généré automatiquement. Donc, ce que vous pouvez faire, c'est simplement fournir à la fonction de champ qu'elle contient la valeur false, comme ceci. Et maintenant, lorsque vous regardez à nouveau la définition de Denise Lives, vous constatez que le champ d'identification ne fait plus partie de l'initialiseur, mais qu'il fait toujours partie de la personne nous voyons ici et qu'il est généré automatiquement. Cela vous permet donc d' avoir un certain contrôle sur ce à quoi ressemblera l'initialiseur tout en ayant cette très belle vue d'ensemble de tous les attributs de l' instance. Une autre chose que vous pourriez faire est peut-être d'ajouter une chaîne de recherche à cette personne. Supposons que nous ayons une chaîne de recherche. Variable d'instance, oui, c'est une chaîne. Et ce que nous voulons maintenant, c'est que la valeur ici soit dérivée du nom et de l'adresse. C'est donc ce que nous voulons être capables, Sergio. Mais bien sûr, ici, nous pouvons encore définir cette valeur car nous ne disposons pas de ces valeurs. Il s'agit simplement d'une spécification des attributs de l'instance. Donc, ce que nous pouvons faire à la place, c'est simplement fournir un champ et le définir comme étant faux, car nous ne voulons pas pouvoir fournir la chaîne de recherche dans le cadre de l'initialiseur. Mais alors, ce que nous pouvons faire, c'est y définir un coup de pouce. Les méthodes Dunder ne renvoient aucune chaîne de recherche à points automatique égale. Ensuite, nous allons simplement construire la chaîne self.name et l'adresse self point, comme ceci. Maintenant, ce qui se passe, c'est que les deux entrées sont appelées après la création de l'objet . C'est alors que nous avons le nom et la valeur de l'adresse, puis nous pouvons calculer la chaîne de recherche. Donc, lorsque j'exécute ce code, encore une fois, vous voyez que nous avons maintenant toutes ces valeurs ici, mais nous voyons également que nous avons une chaîne source qui est le nom plus un espace, puis l'adresse. Alors, que pouvons-nous faire d'autre ? Peut-être que nous ne voulons pas du tout que la chaîne de recherche apparaisse lorsque nous imprimons la personne parce que c'est sorte de double inflammation, n'est-ce pas ? Vous pouvez imaginer que si la classe de personnes augmente, cette chaîne de recherche deviendra très longue. Donc, au lieu de l'imprimer, chaque fois que nous imprimons person, nous pouvons également ajouter ici un rappeur égal à faux. Et cela signifie simplement que lorsque nous imprimons la personne chaîne de recherche ne fera pas partie de la représentation. Il ne sera pas inclus. C'est ce que vous voyez ici. Et pour clarifier, cette chaîne de recherche est en fait quelque chose d' interne à la classe. Vous pouvez également décider de mettre un trait de soulignement devant, comme ça. Et maintenant, nous établissons cette distinction encore plus clairement dans la définition de classe elle-même. Nous pouvons également contrôler la façon dont les objets sont créés. Nous avons donc ici une personne, nous fournissons un nom et une adresse, mais si vous le souhaitez, nous pouvons supprimer ces arguments, noms de mots clés ici et maintenant, cela fonctionnera bien sûr toujours. C'est ainsi que les classes fonctionnent par défaut en Python, n'est-ce pas ? Et si vous vouliez vous assurer de ne pouvoir le fournir qu'en utilisant arguments de mots clés que vous devez toujours écrire, nom égal et adresse égal. Eh bien, vous pouvez le faire en passant un argument ici au décorateur de classe de dates, et c'est uniquement un mot clé et par défaut, c'est faux, mais nous pouvons le définir sur true. Et maintenant, nous voyons que nous obtenons en fait une erreur car elle attend des mots clés. Maintenant, nous devons écrire que le nom est égal à John et l'adresse est égale à 123 rues principales. Pour que cela fonctionne, cela n'a aucun effet sur le résultat réel, le résultat réel, mais cela affecte la façon dont nous pouvons créer des personnes. Et cette rigueur supplémentaire peut parfois être un outil utile. Vous pouvez également geler une classe de données. Cela signifie que vous pouvez modifier l'objet une fois qu'il a été créé. Et nous le faisons en fournissant les produits surgelés ainsi. Mais maintenant, quelque chose d'intéressant se passe. Vous voyez que notre idée de chaîne de recherche ne fonctionne plus car, bien sûr nous avons maintenant un objet figé, ce qui signifie que nous pouvons le modifier, mais nous le modifions toujours après sa création. Je vais vous montrer une autre façon d'aborder cela dans une minute. Donc, pour le moment, permettez-moi de supprimer ceci. Nous utiliserons autre chose plus tard pour résoudre ce problème. Maintenant, quand je l'exécute, bien sûr, cela fonctionne toujours, mais maintenant, quand j'essaie de modifier la personne, le nom de point de la personne est égal, vous voyez que nous ne sommes pas autorisés à le faire. La personne est gelée et reçoit une erreur lorsque vous l'exécutez Vous voyez également que nous obtenons une erreur d'instance gelée. C'est très utile si vous voulez vous assurer que si vous utilisez certaines données, vous ne les modifiez pas accidentellement. Mais comment résoudre ce problème de chaîne de recherche maintenant, car nous ne sommes pas autorisés à modifier cet objet après sa création. Eh bien, une chose que vous pouvez faire est d'utiliser des propriétés à la place. 6. Cours de premier niveau 2/4: C'est un autre ajout très intéressant aux classes qui vous permet de les rendre beaucoup plus puissantes. Ce que vous pouvez faire, c'est qu' au lieu de l'utiliser, vous pouvez utiliser une propriété pour définir un terme de recherche. Je vais donc avoir une propriété ici, et disons que c'est une chaîne de t-shirts haut de gamme. C'est presque comme une méthode. Et cela renverra une chaîne. Et je vais simplement le supprimer ici. Et la chaîne de recherche sera une chaîne f contenant self.name, self.age, address, etc. Il est donc toujours gelé. Mais maintenant, supprimons cela à nouveau. Quand j'imprime la personne. Eh bien, la chaîne de recherche n'est pas là à cause de la propriété, mais nous l'avons, donc je peux imprimer le point personnel, la chaîne de recherche, etc. Il se plaint qu'il s' agit d'un membre privé maintenant, mais comme vous le voyez, il fonctionne réellement dans ses publications. sûr, si vous souhaitez que la chaîne de recherche soit plus accessible au public, vous pouvez bien sûr supprimer ce trait de soulignement de cette manière. Et maintenant que l'erreur des pylônes se répète autour de nous, nous obtenons toujours les mêmes résultats. Donc, une fois que nous avons ajouté, voici une propriété en lecture seule, également appelée getter. Et il est lu uniquement parce que nous ne pouvons rien lui attribuer. Si la chaîne de recherche par points est égale à une valeur élevée, vous verrez que nous obtenons une erreur indiquant que nous ne pouvons pas attribuer un membre à une propriété qui n'est pas autorisée. Ce que vous pouvez faire si vous souhaitez que la chaîne de recherche soit modifiable, c'est d'ajouter un setter. Et comme la source, par exemple , la propriété, c'est très facile en Python. Nous écrivons simplement la chaîne de recherche point, puis nous avons ici un setter de points. Ensuite, nous redéfinissons simplement le même nom de propriété. Mais il accepte un argument qui est la valeur. Cette coque est une chaîne. Il va renvoyer une valeur nulle. Et puis ici, nous pouvons définir la valeur. Bien entendu, cela ne fonctionnera pas parce que nos classes de données sont bloquées, accord, nous pouvons donc tout modifier. Donc, si nous supprimons cela , nous pouvons maintenant stocker des choses. Et comment vous pourriez stocker une valeur dans l'objet si vous le vouliez. Mais bien sûr, nous n'en avons pas vraiment besoin dans le cas de la chaîne source car nous renvoyons simplement une valeur calculée ici, j'ai un autre exemple ici qui a un peu plus de sens en termes de propriété. J'ai donc un clip vidéo de classe qui contient des minutes et des secondes, un titre. Et vous voyez que nous sommes une propriété appelée durée. Et en gros, en fonction du nombre de minutes et du nombre de secondes, on obtient un total de secondes. Et puis nous pouvons également avoir un setter qui définit un nombre de secondes. Et cela utilise essentiellement la fonction div mod pour calculer la valeur supposée des minutes et des secondes. Vous voyez donc ici un exemple d'utilisation d'une propriété, un getter et d'un setter pour contrôler la façon dont les valeurs sont stockées. Objet, dans ce cas, minutes et secondes du clip vidéo. Et voici un projet vidéo qui contient une liste de clips vidéo. Et encore une fois, il s'agit d'un champ utilisé comme liste d'usine par défaut. Nous avons une valeur par défaut pour notre titre, puis nous avons également une propriété correspondant à la longueur totale, savoir la somme de chacun de ces clips, le nombre de minutes et de secondes. Ensuite, j'ai une fonction principale simple où j'ai deux clips. L'un est un clip vidéo d' une minute et 30 s, un autre clip vidéo de 2 min et 30 s. Et puis je crée un projet contenant ces deux clips. J'imprime la longueur totale , puis j'utilise le paramètre de durée pour changer la durée du clip, durée 220 s, soit 2 minutes en fait. Ensuite, nous pouvons imprimer la longueur totale du projet. Et puis quand je lance ça, voici ce que nous obtenons. Nous obtenons donc 240, mais ensuite nous passons de 1 min à 2 min. Cela fait donc trente secondes de plus. Cela fait donc 270 s qui sont en cours d'impression. Ou vous pouvez également voir que si j'imprime le clip ici, Friends en extrait un et je réexécute ce code. Vous voyez qu'après avoir mis à jour le clip, vous voyez que nous avons 2 minutes et 0 s. Et c'est exactement la durée de chaque dose. Et si vous regardez un projet vidéo, nous pouvons le simplifier encore plus, car voici les minutes d' Eclipse point, blocs de points, les secondes. Eh bien, nous pouvons simplement utiliser le temps qu'elle passe ici pour le raccourcir encore. Ensuite, nous allons obtenir exactement le même résultat qu'avant. Ce sont donc des propriétés qui peuvent être utiles pour obtenir une valeur calculée sans avoir à stocker cette valeur. Ils vous aident également à masquer certaines données de bas niveau dans une classe, par exemple si vous avez des minutes et des secondes en interne, mais que vous utilisez simplement les secondes effectuées en externe, un getter et un setter de propriétés vous aideront à y parvenir. 7. Cours de premier niveau 3/4: encore deux choses dont je voudrais parler avant de terminer cette leçon. L'un est une chaîne contre une enveloppe. Nous avons donc constaté que si vous avez une classe de données telle que cette classe de personnes, et que nous imprimons la personne que nous voyons, nous obtenons une sorte de version conviviale pour les développeurs de ce qu'est réellement la personne, qui est utile pour le débogage ou si vous souhaitez verrouiller quelque chose ou quoi que ce soit d'autre. Et c'est exactement ce que l' emballage est censé faire. Wrapper est censé vous donner représentation d'un objet conviviale pour les développeurs. L'idée est même que vous devriez être capable de stocker cette représentation dans un fichier et qu'elle contienne suffisamment d'informations pour plus tard, si vous souhaitez la lire à nouveau dans un fichier et recréer l'objet qui soit différent d'une représentation conviviale. Ce n'est pas quelque chose que vous voulez qu'un utilisateur voie parce que c'est un peu difficile à lire, à écrire. Et c'est là que la méthode dominante des chaînes est quatre. Donc, si vous souhaitez également avoir une représentation plus conviviale d'un objet, vous pouvez utiliser les méthodes string dunder. classe de données ne l'ajoute pas, mais vous pouvez l'ajouter vous-même simplement en ajoutant les méthodes String Dunder. Et bien sûr, cela va renvoyer une chaîne, n'est-ce pas ? Et que voulons-nous retourner ? Disons que nous voulons simplement imprimer le nom de la personne. C'est donc un nom à point fixe, comme ça. Maintenant, lorsque nous exécutons à nouveau ce programme, vous voyez qu'il affiche simplement le nom. Et c'est parce que String Dunder l'emporte sur le rappeur, non ? Donc, si vous n'avez pas de chaîne, mais que vous avez un rappeur Python utilisera un wrapper. Si vous avez une chaîne, elle l' utilisera à la place. Mais que faire si vous souhaitez toujours imprimer la version enveloppante de la personne ? Eh bien, il existe plusieurs façons de procéder. La première est que vous pouvez utiliser la fonction wrapper de cette manière. Et cela va simplement appeler la méthode wrapper dunder, puis renvoyer sous forme de chaîne que nous pouvons maintenant imprimer. Donc, si je fais cette marguerite, nous aurons notre personne, une personne sympathique pour les développeurs. Encore une fois, vous pouvez également utiliser des chaînes de caractères. Donc, si vous avez une chaîne f comme celle-ci, et maintenant, bien sûr, imprimez simplement la personne. Encore une fois, cela affichera la méthode String Dunder, mais vous pouvez en fait utiliser le point d'exclamation R. Et dans une chaîne F, cela affichera également la version wrapper des objets sur lesquels vous avez un certain contrôle sur le Et dans une chaîne F, cela affichera également la version wrapper des objets sur lesquels vous avez un certain contrôle sur le type de contenu imprimé, même si vous avez peut-être à la fois des méthodes wrapper et String Dunder. C'est bon à savoir. 8. Cours de premier niveau 4/4: La dernière chose que je veux vous montrer est un moyen simple d'améliorer la vitesse d'accès aux éléments de vos objets. Et c'est en utilisant des machines à sous. Normalement, Python utilise un dictionnaire pour stocker les valeurs des variables d'instance d'un objet. Et l'accès aux dictionnaires est rapide, mais pas incroyablement rapide. Et si ce n'est pas si rapide, c'est parce que c'est assez dynamique. Vous pouvez ajouter des clés et des valeurs à tout moment. Vous pouvez donc décider de modifier dynamiquement l'objet et d'ajouter nouvelles variables d'instance à tout moment. Python est un langage très dynamique. N'oubliez pas qu'en ce qui concerne les créneaux horaires, vous convenez avec l'interprète que vous allez être un peu plus strict. Vous allez avoir un ensemble fixe de variables d'instance. De ce fait, Python peut optimiser les choses et y accéder beaucoup plus rapidement. Maintenant, dans la plupart des cas, vous aurez en fait un nombre fixe de variables d' instance. Vous ne voulez pas changer d'objets tout le temps, partout, n'est-ce pas ? Ça va tourner au bordel. Donc, si vous le faites et que vous en utilisez beaucoup, ce sera en fait beaucoup plus rapide. Voici donc un exemple très simple qui utilise à nouveau des classes de données, une option d'emplacements. Ainsi, si vous avez une classe de données, vous pouvez simplement définir les emplacements sur true, comme je le fais ici. Ensuite, il utilisera des machines à sous au lieu du dictionnaire traditionnel. J'ai donc une version de la classe person, n'en utilise pas beaucoup et une version de la première classe qui les utilise. Et puis j'ai une fonction, celle Elite qui permet d'attribuer des créneaux à une personne ou à une personne, et qui permet de définir l'adresse, lire l'adresse et de la supprimer , comme une sorte de point de référence. Et puis j'ai la fonction principale qui consiste à créer des personnes, des machines à sous et une personne normale. Ensuite, j'utilise Time it to repeat pour appeler la fonction Get Set Delete de la personne. Beaucoup de fois, dans ce cas, 1 million de fois. En fait, je prends la valeur médiane pour obtenir les performances médianes et je vais imprimer combien de temps. C'est bon, les performances s' améliorent. Au fait, ce truc est partiel. J'en parlerai dans la prochaine leçon. Alors restez à l'affût. Alors laissez-moi le lire maintenant, nous pouvons voir ce qui se passe. constatons maintenant que lorsque nous n'avons pas d'emplacements toutes ces opérations d'accès, de lecture, d' écriture et de suppression prennent 0,06 s avec les emplacements, cela prend 0,05 s. donc une amélioration des performances de près de 20 %, surtout si vous traitez de nombreuses données, alors cela aura vraiment un impact important si vous effectuez ces opérations partout. C'est donc très simple, il suffit de définir les emplacements sur true lorsque vous définissez votre classe de données. Vous pouvez désormais bénéficier de cette amélioration, car les emplacements d' amélioration de la vitesse utilisent également un peu moins de mémoire. Il y a cependant quelques mises en garde. La première est que si vous utilisez plusieurs emplacements d' héritage , cela peut entraîner des problèmes. Soyez donc très prudent avec cela, mais vous devez, dans tous les cas, faire attention à l'utilisation de l'héritage multiple. Et une autre chose est que vous les comptez dynamiquement en ajoutant ou en supprimant des variables d' instance, deux objets parce que emplacements étaient un peu plus stricts. Mais je pense que dans l'ensemble, c'est une bonne chose. Cela conclut cette leçon où je vous ai montré quelques choses plus puissantes que vous pouvez faire avec les classes en Python. Dans la leçon suivante, je vais parler de ce que vous pouvez faire avec les fonctions. Et je vais également examiner de plus près certains outils fonctionnels de Python pour vous aider à le faire. 9. Fonctions de premier niveau: Dans cette leçon, je veux parler des fonctions et de certaines des choses les plus puissantes que vous pouvez faire avec les fonctions en Python, comme nous l'avons fait avec classes et dans la leçon précédente. En Python, en gros, tout est un objet, n'est-ce pas ? Nous avons des entiers, des chaînes de caractères, des classes dont vous pouvez créer des objets. Même une fonction est un objet, c'est un objet de type double. Et vous pourriez en fait, si vous vouliez créer une classe dotée d'un appel à des méthodes dunder, cette classe est également une classe de rappel qui se comporte également comme une fonction. En fait. Voici un exemple très simple j'ai une classe de clients, c'est une classe de données. Si vous dormez avec un nom, un âge et leur fonction, voici une promotion appelée Envoyer un e-mail, qui permet d'obtenir une liste de clients et qui est utilisée pour passer en boucle les clients qui consultent le client. Si l'âge est d'environ 50 ans, le client est éligible à la promotion. Et si l' âge du client est supérieur à 50 ans, il est éligible à la promotion. Et en fonction de cette valeur, nous imprimons quelque chose de différent à l'écran. Ensuite, j'ai une fonction principale qui crée une liste de clients, puis envoie des promotions par e-mail à ces clients. Au moins ceux de plus de 50 ans ont contourné cette procédure, puis voici ce que nous obtenons. Il vérifie donc chaque client , puis indique s' il est éligible ou non pour envoyer promotion par e-mail. Il s'agit d'une fonction appelable, qui permet d'obtenir la liste des clients et des retours, aucune. Et bien sûr, c' est une utilisation très basique de la fonctionnalité en Python, n'est-ce pas ? Mais comme la fonction est un objet, vous pouvez en fait faire beaucoup plus de choses avec elle. Par exemple, vous pouvez transmettre une fonction à une autre fonction ou même demander une fonction de renvoyer une autre fonction en conséquence. Et c'est ce que nous faisons. C'est lorsque vous utilisez ce que l'on appelle les fonctions de commande supérieure. Par exemple, ici, nous vérifions que si le client est âgé d'environ 50 ans, il est éligible à la promotion. Mais peut-être voulons-nous procéder à une vérification plus complexe , qui permettrait également de vérifier les informations concernant le client. Bien entendu, nous pourrions étendre l'énoncé if de plus en plus complexe à la condition. Mais il serait également intéressant que l'envoi promotions par e-mail puisse bénéficier un mécanisme permettant de vérifier l'éligibilité en appelant une autre fonction. Et c'est ce que nous pouvons faire avec des fonctions d'ordre supérieur. Donc, ce que nous pouvons faire à la place, c'est définir qu'une fonction est éligible à une promotion ET fonction va attirer un client. Et il va renvoyer un booléen. Et cela indiquera simplement au client que le point h est supérieur à 50. Comment utilisons-nous cette fonction ici ? Eh bien, on peut simplement l'appeler, non ? Nous pouvons le faire s'il est éligible à la promotion. Un client, comme ça. Ensuite, lorsque nous exécuterons ceci et ce, nous obtiendrons exactement les mêmes résultats. Mais cela nous donne encore très peu de contrôle, car il est désormais impossible définir d'autres fonctions et de déterminer ensuite de manière dynamique si nous devons envoyer un e-mail aux clients ou non. C'est toujours une fonction spécifique au disque. Ainsi, au lieu de l'appeler directement ici, nous pouvons également le transmettre comme argument pour envoyer une promotion par e-mail. Supposons donc que la fonction soit éligible pour l'écrire correctement. Évidemment, puisqu'il s' agit d'une fonction, nous nous attendons à quelque chose de type goal, c'est une fonction. Et comment spécifier quel type de maladie fonctionnelle ? Eh bien, nous utilisons les crochets puis nous utilisons une autre paire de crochets pour indiquer quels sont les arguments de cette fonction avec les types de paramètres. Donc, ce que cette expression est un client et ce qu' elle renvoie sont booléens. Et puis, au lieu d' appeler le dysfonctionnement directement ici, nous appelons la fonction que nous transmettons en paramètre de la manière suivante. Et maintenant, bien sûr, nous devons nous assurer que lorsque nous appelons réellement la fonction ici, vous voyez qu'il y a également une erreur que nous transmettons. Cette fonction particulière est éligible à la promotion. Comme ça. Maintenant, lorsque nous l' exécutons, nous obtenons exactement le même résultat, mais maintenant nous l'avons fait, en le répartissant un peu différemment, et maintenant nous utilisons fonctions d' ordre supérieur afin de séparer la fonction de promotion par e-mail et la fonction de vérification d'éligibilité. Maintenant, au lieu d'avoir à définir une fonction comme celle-ci , vous pouvez également utiliser une fonction lambda. La fonction Lambda en Python est une fonction anonyme. Nous n'avons donc pas ici fonction anonyme car cette fonction a un nom. La fonction Lambda n'a pas de nom et vous spécifiez directement sous forme d'expression. Ainsi, au lieu d'avoir cette fonction ici, à laquelle nous faisons référence par son nom, nous pouvons utiliser une fonction lambda. Cela va attirer un client et cela va renvoyer c, H est au moins 50. Et maintenant, lorsque nous exécutons cela, nous obtenons à nouveau exactement le même résultat. Mais maintenant, nous utilisons une fonction lambda anonyme. Et c'est bien parce que nous avons maintenant moyen très simple de modifier la façon dont les promotions par e-mail sont traitées avec le code d'erreur. Par exemple, nous pouvons également modifier l'âge, disons seulement au-dessus de 60 ans. Et maintenant, nous allons obtenir un résultat différent. Et nous n'avons rien eu à modifier dans la fonction de promotion « Envoyer un e-mail », qui est vraiment sympa. 10. Fonctions de premier niveau 2/4: Faisons en sorte que cet exemple soit un peu plus compliqué. Je vais à nouveau supprimer la fonction Lambda, et je vais appeler est éligible une fois de plus. Je vais vous montrer un autre moyen mieux contrôler ce qui se passe lorsque vous appelez une fonction. Bien entendu, si nous sommes éligibles à une promotion, éligibles à une promotion, nous n'avons aucun moyen de contrôler réellement cette valeur, car elle est codée en dur dans la fonction. Nous pourrions donc avoir la possibilité d'avoir un âge limite, qui sera un entier. Et puis au lieu d' utiliser les 50 ans, nous pouvons utiliser la croix de huit, n'est-ce pas ? Donc c'est vraiment sympa. Mais nous avons maintenant un problème éligible à la promotion. Bien entendu, cela ne correspond plus au type de crédulité que nous avions ici. Et c'est parce qu'il y a maintenant ce paramètre supplémentaire que nous devons fournir. Vous pouvez faire une chose, par exemple fournir une valeur par défaut. Et puis c'est une sorte de solution de contournement, car maintenant cela fonctionne à nouveau. Mais maintenant, il n'y a toujours aucun moyen de modifier l'âge ici de quelque manière que ce soit, car nous ne pouvons utiliser que la valeur par défaut, n'est-ce pas ? Maintenant, c'est là que le package funk tools peut nous fournir une solution intéressante appelée application à fonctions partielles. Que signifie l' application Parcel Function ? Cela signifie essentiellement que si vous avez une fonction avec deux paramètres différents comme celle que nous avons ici, c'est-à-dire qu'avec partial, vous pouvez déjà appliquer certains de ces arguments. Et puis tu retrouves une autre fonction. Lorsque vous appelez cette fonction, les arguments que vous avez appliqués précédemment seront utilisés. Cela vous permet donc de modifier la signature de l'en-tête de la fonction en fournissant déjà certaines valeurs. Donc, par exemple ce que nous pouvons faire ici, c'est d' abord importer à partir d'outils, qui est le modèle que nous allons utiliser. Ensuite, ce que vous pouvez faire, c'est supprimer à nouveau cette valeur par défaut, afin de supprimer l'erreur. Vous pouvez maintenant dire, eh bien, nous l'avons fait, est éligible. Et supposons que nous voulions couper à 60 ans, donc nous allons dire que c'est éligible à 60 ans, ce qui est une demande partielle d'éligibilité à une promotion. Mais nous allons lui fournir un âge limite de 60 ans. Et maintenant, lorsque nous avons envoyé une promotion par e-mail, nous pouvons l'envoyer, nous pouvons lui fournir les 60 fonctions partiellement appliquées éligibles. Donc, partial obtient une fonction. Elle applique une valeur à l'un de ses arguments et renvoie une nouvelle fonction , désormais appelée is eligible 60. Malheureusement, nous ne savons pas exactement quel est le type de cette fonction partiellement appliquée. Peut-être dans une future version de Python, mais il s'agit à nouveau d'une fonction qui est maintenant appelée par des promotions envoyées par e-mail. Quand je l'exécuterai, vous aurez des clients âgés de plus de 60 ans. Il s'agit donc d'un exemple d' application à fonctions partielles vraiment puissante qui vous permet de modifier des fonctions, les simplifier et de les utiliser, les rendre compatibles avec d'autres domaines de votre application en appliquant déjà certaines des valeurs. 11. Fonctions de niveau 3/4: Une autre bonne chose que vous pouvez faire avec les outils func est ce que l'on appelle la propriété en cache. Vous vous souvenez peut-être de l'exemple que je vous ai montré dans l'une des leçons précédentes où j'avais une personne et nous avions une propriété de chaîne de recherche, qui était une propriété calculée. Ainsi, chaque fois que vous appelez la propriété, la valeur est informatique. est peut-être pas toujours ce que vous voulez si la valeur doit calculer trois, complexe à calculer, eh bien, avec la chaîne de recherche, ce n'était pas si mal. Mais si c'est vraiment complexe, vous voulez éviter d'avoir à le calculer à chaque fois que vous appelez la propriété. Une façon de le résoudre est de stocker la valeur dans l'objet que vous avez calculé lorsque vous créez l'objet. Mais si vous utilisez une classe de données figée, cela n'est pas possible. C'est là que les propriétés mises en cache entrent en jeu à partir des fonctions. Voici donc un exemple de la façon dont il est utilisé. J'ai un ensemble de données de classe qui contient une séquence de nombres. Et dans ce cas, je le stocke simplement sous forme de tuple dans une variable d'instance de données. Et puis j'ai la trésorerie, qui correspond à l'écart type de ces données particulières. Et j'utilise la fonction d' écart type à partir des statistiques. Et puis après la fonction principale où crée essentiellement une instance de cet ensemble de données. Ensuite, j'imprime l'écart type. Et ce qui est vraiment intéressant, c'est que si je le lance maintenant, vous verrez que nous n'obtenons qu' une fois le message qui calcule l' écart type. Et c'est parce que cela est mis en cache. La propriété est calculée une fois et chaque fois que vous appelez ensuite, elle utilise simplement la valeur mise en cache. C'est donc vraiment puissant si je devais utiliser une propriété normale pour cela. Comme ça. Et maintenant, je le répète, vous voyez que l' écart type est calculé trois fois. C'est ce qui fait la différence. Je vais donc transformer cette véritable propriété en espèces. Et maintenant, lorsque nous l'exécutons à nouveau, il n'est à nouveau calculé qu'une seule fois. Vous utilisez donc une propriété monétaire pour mémoriser certaine valeur. Vous n'avez donc pas à les calculer encore et encore, tout en ayant la possibilité d'y accéder comme une propriété normale dans votre objet. 12. Fonctions de niveau 4/4: dernière chose cool que je veux vous montrer depuis Fontanelles, c'est une dépêche unique. Single Dispatch est un décorateur que vous pouvez utiliser pour surcharger une sorte de fonction. Vous définissez donc une fonction générique et enregistrez des variétés de cette fonction qui peuvent gérer différents types. Voici un exemple. J'ai une seule fonction de répartition appelée add qui a un x et un y, deux entiers, et qui renvoie la somme de deux entiers. Mais j'ajoute ensuite une deuxième version de cette fonction. Il s'agit donc, disons, de la version par défaut de la fonction qui obtient des entiers. Le second qui reçoit des chaînes et des chaînes. Je ne veux pas les ajouter directement comme ça. Je souhaite ajouter un espace. J'utilise donc la mise en forme de chaîne ici pour insérer un espace entre le x et le y. J'y reviendrai dans une minute, mais si nous avons ici imprimé 12 et imprimons Hello World, alors vous verrez que la première ligne indiquant qu'elle va imprimer est bien la somme et les chaînes concaténées avec l' espace entre elles. Et il y a d'autres choses que vous pouvez faire avec ça. Vous pouvez par exemple également utiliser le type d'union dont j'ai parlé dans la vidéo de saisie. J'enregistre donc ici une version de cette fonction qui prend un x et un y, c'est soit une liste, soit un ensemble. Et cela renvoie une liste, enchaînant simplement les éléments de la liste des ensembles. Et il existe également une forme fonctionnelle. Ceux-ci utilisent donc un soi-disant décorateur avec le signe d'ajout devant celui-ci. Mais vous pouvez aussi simplement appeler le registre par points en tant que fonction et vous fournissez le type , puis la fonction qui doit le gérer. C'est donc ce que vous voyez se faire ici. Je peux donc simplement réexécuter cette liste et celle de l'OCDE à renvoyer. Et le dernier renvoie un tuple parce que c'est ce que nous avons spécifié ici. Émettez un tuple plus rapide, puis vous renvoyez également un tuple. Vous pouvez donc utiliser une répartition unique pour gérer facilement des objets de différents types en Python. Pour être honnête, je ne l'ai pas beaucoup utilisé, mais je pense qu'il est utile de savoir que cela existe. Et dans certains cas, il peut être utile de simplifier un peu votre code. Donc, dans l'ensemble, je pense que la bibliothèque d'outils funk est une collection d'outils vraiment intéressante. Il y a aussi quelques autres choses qui n'ont pas été abordées dans cette leçon d'aujourd'hui. Vous pouvez consulter la documentation. Mais dans l'ensemble, je pense que c'est vraiment intéressant. Comme j'ai également remarqué, beaucoup de gens ont tendance à s'en tenir aux cours, alors que les fonctions sont également très puissantes. Par conséquent, ils vous permettent également souvent de simplifier votre code au lieu d' utiliser des classes partout. La prochaine fois que vous écrirez un programme Python, vous aurez affaire à des classes complexes et à tout le reste. Réfléchissez à la façon dont vous pouvez en faire une version plus fonctionnelle. Et vous remarquerez souvent que le code sera plus court et plus facile à lire. Ce sont donc des outils amusants et une sorte de programmation fonctionnelle en Python. leçon suivante, je vais jeter un œil à autre concept que vous voulez trouver vraiment utile, à savoir programmation concurrente. 13. Programmation simultanée 1/3: Surtout si vous commencez à utiliser Python de manière plus professionnelle, vous allez soudainement interagir avec une API, une base de données, etc., essentiellement via un réseau. Et si vous le faites, cela signifie qu'il devient important pour votre application de traiter efficacement ces types de demandes. Parce que si vous ne le faites pas, votre application sera très lente. En Python, vous pouvez utiliser le package d'E/S asynchrone pour vous aider. Et cela repose sur ce que l' on appelle la programmation concurrente. Vous avez peut-être déjà entendu le terme simultanéité de programmation concurrente et le terme apparenté parallélisme, programmation parallèle. Ces choses ne sont en fait pas la même chose. Il y en a différents. La différence réside dans le fait que le calcul parallèle signifie que vous disposez en fait d'unités de traitement parallèles distinctes pour effectuer des tâches distinctes. Donc, si vous avez une application qui fait plusieurs choses en même temps, ces tâches sont en fait effectuées en parallèle en même temps. C'est du parallélisme et la simultanéité signifie qu'une application progresse sur plusieurs tâches en même temps. Mais au lieu d'avoir de véritables opérations parallèles, il va en fait basculer dynamiquement entre ces tâches. Disons qu'une application va de la tâche A à la tâche B, elle va simplement commencer à faire un peu d'une opération continue avec a, continuer avec B, un bit de B, puis revenir à a et ainsi de suite. Ce n'est donc pas parallèle, mais il s'agit simplement de passer de l'un à l'autre. Parce que ça va très vite. En tant qu'utilisateur, vous pouvez avoir l'idée que cela se produit en parallèle, mais en réalité, cela se produit simultanément. Il s'agit simplement de changer. C'est comme la différence entre les files d'attente parallèles devant un caissier. Cela signifie que nous avons plusieurs caissiers et chaque caissier a une ligne qu'il traite. La simultanéité signifie qu' il n'y a qu'un seul caissier, mais qu'il y a plusieurs files d'attente et que tout le monde se relaie. Dans ce cas, les files d'attente correspondent aux tâches qu' un ordinateur doit résoudre et les caissiers sont les processeurs. Les ordinateurs modernes utilisent une combinaison de parallélisme et de simultanéité. Vous savez, votre processeur peut avoir 246810 cœurs qui peuvent tous faire des choses en parallèle, mais votre système d'exploitation aura des dizaines, voire des centaines de tâches différentes. Et il va exécuter un sous-ensemble de ces tâches en parallèle sur ces différents cœurs de processeur, mais il va également basculer entre elles simultanément. parallélisme en Python comporte une mise en garde en ce que Python possède ce que l'on appelle un verrou d'interpréteur global. Cela signifie que si vous avez, disons, plusieurs threads censés être parallèles, qui pourraient l'être en fait en Python, cela ne fonctionne pas car ils sont verrouillés sur l'interpréteur. Il y a des raisons à cela. Je n'aborderai pas cela dans cette leçon. Mais les conséquences du parallélisme en Python ne sont pas vraiment possibles. Il existe quelques solutions de contournement, par exemple vous pourriez, au lieu d' avoir un seul processus, utiliser le backedge multitraitement pour créer plusieurs processus. Et Dan, tu as du parallélisme. Vous pouvez également passer à un autre interpréteur Python qui ne possède pas ce verrou d' interpréteur global. Mais en réalité, il n'y a pas beaucoup de cas où vous avez besoin du parallélisme. Souvent, la simultanéité est déjà très bonne et Python prend très bien en charge la concurrence, en particulier depuis Python 3.7, qui a en particulier depuis Python 3.7, considérablement amélioré le package Async IO. La simultanéité est désormais très importante car elle vous permet d'avoir plusieurs tâches, par exemple une tâche pour récupérer des données à partir d'une API. En attendant la réponse de l'API, vous pouvez déjà passer à une autre tâche, ce qui est également utile, par exemple si vous avez une application graphique et que l'interface graphique attend que vous saisissiez du texte dans les champs de texte ou que vous appuyiez sur un bouton. Eh bien, comme il s'agit d'un programme simultané, vous pouvez effectuer d'autres tâches en même temps, comme nettoyer une partie de la mémoire, préextraire des données ou faire tout ce que vous voulez pour améliorer le fonctionnement de l'application . Et étant donné que presque toutes les applications communiquent aujourd'hui sur Internet et récupèrent un tas de données. Il est très important gérer correctement la concurrence. Et c'est ce que le package Async IO de Python vous permet de faire. 14. Programmation simultanée 2/3: Il existe deux mots clés importants que vous devez connaître si vous écrivez du code simultané ou asynchrone, l'attente asynchrone. Vous pouvez écrire une fonction asynchrone devant une fonction ou une méthode pour indiquer qu'il s'agira d'une fonction ou d'une méthode que vous pouvez appeler simultanément. Vous pouvez également utiliser une pondération pour indiquer devant une déclaration que la déclaration suivante doit attendre la fin de la déclaration précédente. Et c'est la deuxième partie qui est également très utile car vous devez souvent attendre une certaine réponse pour faire quelque chose. Par exemple, si vous récupérez des données à partir d'une API, vous devez attendre de récupérer deux données pour pouvoir réellement faire quelque chose avec ces données. Async et wait ont donc un exemple très simple ici. Vous pouvez voir que nous avons une fonction obtient Pokémon qui utilise l' API Pokemon pour obtenir les noms des Pokémon. Et nous transmettons, dans ce cas, un identifiant et nous avons une URL à laquelle nous fournissons l'identifiant. C'est ainsi que nous devons appeler cette API. Et puis je reviens en attendant HTTP GET. Et puis l'URL http get est une fonction d'assistance que j'ai créée. C'est asynchrone. Je vais vous montrer comment cela fonctionne dans une minute. Mais ici, nous voyons la fonction asynchrone Get Pokemon qui renvoie les poids, puis récupère les données de l'URL. Et nous faisons appel à un serveur car, bien entendu, nous ne pouvons revenir qu'une fois que nous avons ces données. La fonction principale ici, comme vous pouvez le voir ici, est également asynchrone car, eh bien, elle utilise la fonction rent int pour créer un entier aléatoire entre un et l'identifiant Pokemon le plus élevé, qui est actuellement 898. Ensuite, j'utilise un poids pour obtenir le Pokémon à partir de cet identifiant en particulier, puis j'imprime le nom du Pokémon. Et ici, le poids est également très important car, bien sûr, je dois attendre d'avoir la valeur Pokemon pour pouvoir imprimer le nom. C'est ce que vous voyez ici. J'ai contourné ça. Vous voyez, nous obtenons des Pokémon au hasard et vous constatez qu'il a fallu environ une demi-seconde ou une seconde pour obtenir cette valeur Pokémon particulière. Essayons encore une fois. Vous voyez, cela prend un certain temps , puis nous obtenons le résultat. C'est faux car nous devons attendre que l'API nous réponde, ce qui peut prendre un certain temps. Voici un autre exemple qui montre à quel point il est utile d'utiliser la programmation concurrente. Donc, ce que j'ai fait ici, c'est que j'ai deux versions pour le faire. Recevez une demande depuis l'API. J'ai une version asynchrone et une version synchrone. Vous avez ici une fonction qui utilise la version synchrone. Donc, ce que je fais, c'est que je reçois Pokemon à partir de cette URL particulière. Et ici, je n'ai pas de version asynchrone qui contient ce Pokémon. Et dans ce cas, j'utilise la fonction HTTP GET asynchrone. Dans ma fonction principale, j'ai alors deux versions après des appels synchrones. Donc, en gros, cela pondère à chaque fois les résultats, n'est-ce pas ? Je fais donc une boucle et j' obtiens 20 noms locaux aléatoires, puis je calcule le temps total. Et dans l'appel asynchrone, j'utilise quelque chose appelé Async IO dot gather. Et cela me permet de lui fournir un certain nombre d' appels et un certain nombre d'appels asynchrones, puis il les lancera, ils veulent toujours des fourmis au lieu d'attendre la fin de chaque mois avant de commencer le suivant collecte asynchrone d'aorte nous permet exécuter toutes ces choses simultanément. Donc, lorsque vous exécutez ceci, vous le voyez alors que c' est la première fois. Vous avez donc vu que dans le cas synchrone, il nous a fallu près de 2 s pour obtenir ces 20 noms de Pokémon , car nous attendons le premier avant de demander le second. Et dans le cas asynchrone, cela n'a pris que 0,9 s, soit moins de la moitié. Et c'est parce que nous gérons les choses simultanément. Nous n'avons pas besoin d'attendre les résultats du premier appel d'API. Pour lancer le deuxième appel d'API, il faut faire attention, à savoir que ces API ont souvent des limites de RAID. Vous ne voulez donc pas lancer 1 000 appels d' API ou ne le souhaitez pas, car cela ne sera pas accepté. Vous devez donc effectuer la demande d'API dans certaines limites de débit, exemple un nombre fixe d'appels, comme le nombre maximum d'appels par seconde, dépend de l'API qui doit le rechercher. Mais comme vous pouvez le constater en réfléchissant un peu façon dont nous pouvons exécuter notre code de manière asynchrone, façon dont il peut s'exécuter simultanément. Cela va nous faire économiser beaucoup de temps d'attente et rendre notre application beaucoup plus fluide. C'est donc rassemblé, rassemblé En gros, ce que vous voyez ici, je déballe une liste de différents appels de fonctions asynchrones. C'est donc async io.gov, qui est un outil vraiment utile pour exécuter des choses simultanément. Et tout ce que l'on peut voir ici dans ces exemples, c'est que nous avons cette fonction principale asynchrone, mais que nous l'exécutons en utilisant un système de points d'E/S asynchrone, qui indique à l' interpréteur Python d'exécuter cette fonction principale de manière asynchrone. Et nous en avons besoin, car si j'écris simplement principal, cela ne fonctionnera pas comme prévu. Parce que si je fais fonctionner cette climatisation, nous recevons toutes sortes d'avertissements indiquant que la co-routine du Maine était de ne jamais l'attendre. Et c'est exactement ce qui se passe ici, bien sûr . Nous l'appelons simplement. Donc, si vous voulez éviter cela, vous devez appeler async IO point run et l'écrire correctement, bien sûr, doctrine. Et puis nous appelons la fonction principale ainsi. Quand je l'exécute à nouveau, vous voyez que nous n'avons plus l' erreur. 15. Programmation simultanée 3/3: La dernière chose que je veux vous montrer est comment transformer du code synchrone non concurrent en code qui s'exécute simultanément. Et cela peut arriver parfois. Vous utilisez peut-être un package de bibliothèque qui n'est pas asynchrone, mais que vous souhaitez le transformer en appel asynchrone. Comment faites-vous cela ? J'ai donc un exemple ici. Il y a donc une fonction asynchrone ici, un compteur, et il y a aussi une fonction d'envoi synchrone de demandes ici. Et cela consiste simplement à utiliser le package de requêtes d' écriture, le package de requêtes n'est pas réellement asynchrone et synchrone. Cela signifie que si nous envoyons une demande ici, nous devons attendre le résultat et simplement renvoyer le code d'état. Dans ce cas, ma fonction principale est ici et j'envoie une demande à our alcohols are gone, qui est mon site Web. Et puis j'imprime la réponse HTTP avec cet état, puis j'appelle le compteur. Une autre question est, bien entendu, pourquoi devrions-nous attendre la réponse ici pour démarrer le compteur ? C'est tout J'en ai besoin, non ? Donc, si je lance ceci, vous voyez que nous envoyons la demande, puis nous avons la réponse, puis nous commençons à contrer. Et si nous voulions utiliser Gathered pour démarrer un compteur en même temps que l'envoi de la demande. Comment faisons-nous cela ? Eh bien, si nous voulons le faire, cela signifie que nous devons activer l' envoi de la demande, etc. Fonction concurrente asynchrone au lieu d'une fonction synchrone, si vous voulez le faire, c' est en fait très simple. Donc, au lieu d'appeler des demandes d' envoi comme celle-ci, vous pouvez utiliser des E/S asynchrones à deux points. Est-ce que cela va en faire un fil de discussion ? Ensuite, nous appelons Send Request. Nous devons également fournir les arguments, à savoir l'URL. Ensuite, nous devons écrire un poids devant, car toute menace transforme cette fonction en fonction asynchrone. Alors laissez-moi exécuter ceci et vous verrez que nous obtenons toujours exactement le même résultat, n'est-ce pas ? Parce que nous n'avons aucun poids. Nous envoyons donc la demande, obtenons la réponse, puis nous démarrons le compteur. Mais maintenant que nous avons la version asynchrone, nous pouvons en fait utiliser asynchrony all dot gather pour faire ces deux choses en même temps. Nous avons donc ici un exemple où j'ai configuré cela. Donc, ce que j'ai fait, c'est créer une autre fonction appelée requête asynchrone envoyée qui utilise un point d'E/S asynchrone pour menacer d'appeler celui-ci de manière asynchrone. Et puis, dans ma fonction principale, je n'ai pas de collecte de points d'E/S asynchrone. Et puis j'ai envoyé la requête asynchrone qui cause un dysfonctionnement, qui menace de transformer cela en une fonction asynchrone. Et j'utilise aussi un compteur. Et quand je l'exécuterai, vous verrez que nous avons le compteur. Et cela commence en même temps que l'envoi d'une demande. Ensuite, nous attendons et, à la fin, nous obtenons la réponse. C'est donc une E/S asynchrone. Enfin, voici notre équipe asynchrone Get Pokemon qui utilisait cette fonction HTTP GET, une fonction d'assistance que j'ai créée. C'est en fait dans ce dossier. Et vous voyez que nous utilisons ici le thread Async IO point two pour transformer la fonction request point gets en un appel de fonction asynchrone. Cela utilise donc exactement le même mécanisme pour conclure que les E/S asynchrones sont une fonctionnalité très puissante de Python. programmation simultanée est généralement très utile, en particulier si vous communiquez via un réseau avec d'autres services et que vous souhaitez que votre application fonctionne correctement. J'espère donc que cette leçon vous a donné quelques idées sur la façon dont vous pouvez transformer votre propre code en code asynchrone, particulier si vous effectuez une grande partie de cette communication avec une API ou une base de données. Dans les quelques leçons restantes de ce cours, il peut que je fasse parfois référence à la programmation simultanée. Montrez comment vous pouvez utiliser cette fonctionnalité en particulier, en tenant compte de la programmation simultanée. Maintenant, la prochaine leçon portera sur les itérateurs. 16. Iterators 1/3: Dans cette leçon, je vais parler des itérateurs en Python. Ce qui n'est pas un itérateur Bien qu'il s'agisse essentiellement d'un objet qui peut être itéré, vous pouvez parcourir toutes les valeurs. Vous pouvez reconnaître un itérateur en Python car il implémente le protocole d'itération, ce qui signifie qu'il possède les méthodes domino suivantes. itérateurs sont omniprésents en Python, ils sont utilisés dans les boucles, ils utilisent la compréhension de listes et bien d'autres endroits où vous les avez probablement déjà utilisés plusieurs fois sans même rendre compte qu'il s' agissait d'itérateurs. Vous avez peut-être entendu les termes itérateur et itérable. Ce n'est pas la même chose. Un objet itérable qui peut vous fournir un itérateur. Cela signifie qu'il utilise la méthode itr dunder car cela vous donne un itérateur. Un itérateur situé à côté de la méthode donatrice itr possède également une méthode dominante suivante qui nous permet d' obtenir l'élément suivant de l'itération. Certains de ces itérateurs sont limités, par exemple vous pouvez parcourir une liste fixe d'éléments. Certains de ces itérateurs sont infinis. Par exemple, vous pouvez itérer sur toutes les valeurs entières. Bien entendu, en Python, il n'y a pas de valeur maximale pour un entier, moins quelques points indiquant que la mémoire de votre ordinateur est limitée. Donc, les listes, les tuples, les dictionnaires, les ensembles, chaînes, ce sont des choses qui sont toutes itérables. Et vous pouvez obtenir un itérateur à partir d'eux, puis vous pouvez itérer sur la séquence en question. Jetons un coup d' œil à quelques exemples. J'ai une fonction principale ici, et il y a un élément de classe qui porte un nom et un poids . Chaque élément a un poids. J'utilise évidemment des classes de données. Et puis après la fonction principale, n'importe où, la liste des objets et j'appelle cela un inventaire. Maintenant, ce que je peux faire, c'est que l' inventaire est une liste, donc c'est un itérable. Je peux donc en obtenir un itérateur. Je peux donc faire un inventaire. L'itérateur est égal à Inventory Dot Dr Hitter. Cela va me donner l'itérateur, puis je pourrai imprimer, par exemple itérateur d'inventaire point, puis Dahmer ensuite. C'est donc en utilisant le protocole d'itération. Si je l'exécute, vous verrez qu'il va imprimer le premier élément de cette séquence itérative. Si je copie cette ligne, comme ça, elle appellera Max deux fois et elle passera au deuxième élément. C'est ce que vous voyez ici. Il existe un moyen légèrement plus simple de procéder au lieu d'appeler ces méthodes inutiles Nous pouvons également faire ce qu'il faut. C'est elle, qui est une fonction auxiliaire qui désigne simplement la méthode dominante pour nous. De même, nous pouvons également utiliser next, qui désigne la prochaine méthode dominante pour nous. Comme ça. Et maintenant, nous obtenons exactement le même résultat. Je peux donc continuer à le faire. Il y a donc six articles ici. Je vais donc maintenant imprimer tous les éléments de cette liste particulière. Alors, que se passera-t-il si j'en ajoute un de plus ? Eh bien, cela va provoquer une erreur d'arrêt de l'itération. Vous voyez donc que nous arrivons ici à un retraçage, il y a un arrêt de l'itération. C'est ainsi qu'un itérateur indique : « Hé, il n'y en a plus, je peux vous donner autre chose. Maintenant, vous pouvez, par exemple créer une boucle while, puis insérer une instruction try except, puis récupérer ces itérations d'arrêt, puis, vous savez, vous êtes stupide. Mais bien sûr, personne n' utilise les itérateurs de cette manière. Ce n'est pas une façon beaucoup plus simple de le faire, et c'est simplement en utilisant une boucle for. Permettez-moi donc de supprimer toutes ces choses ici. Ensuite, je vais écrire pour l'article en inventaire. Ensuite, je vais simplement imprimer le point-virgule de l'article, en fait. Nous y entrons et imprimons simplement tous les articles. En fait, la boucle for utilise la méthode iter et la méthode next. Elle reçoit donc d'abord un itérateur, puis elle appelle next plusieurs fois jusqu'à ce qu'elle rencontre l'erreur d' arrêt de l'itération, puis elle s'arrête. C'est ce que fait la boucle for. Rien d'autre. avantage de la fonction iter qui appelle la méthode donateur, c'est que vous pouvez également lui fournir une valeur sentinelle. Et c'est essentiellement une valeur qui doit être fournie pour indiquer la fin de l'itérateur. Ceci est utile, par exemple, si vous lisez des données à partir d'un fichier ou d'un réseau, essentiellement un flux de données et que vous souhaitez savoir si la fin du flux a été atteinte. J'ai donc un exemple ici. Il s'agit donc d'un fichier appelé country's qui contient quelques pays. Ensuite, je peux utiliser la valeur sentinelle pour indiquer la fin du fichier. Je peux donc utiliser une instruction de largeur. C'est un gestionnaire de contexte. J'en parlerai dans une prochaine leçon. Et je vais utiliser Open, puis je vais ouvrir le fichier TXT à points des pays. Et puis je fais la queue dans une entrée amusante. Et puis il va appeler la ligne de lecture phi point, qui renvoie un itérable. Et la valeur sentinelle sera la chaîne vide. Ensuite, je vais imprimer la ligne. Donc, lorsque nous faisons cela, vous voyez que nous obtenons tous ces pays. Et comme le fichier texte contient déjà de nouvelles lignes, je peux simplement les supprimer de l'instruction print en indiquant que la fin de l'instruction print est une chaîne vide. Ensuite, ça va être un peu plus beau. La chaîne vide ici est donc utilisée comme valeur sentinelle pour indiquer que nous atteignons la fin du fichier. 17. Iterators 2/3: Comme nous avons ces itérables et itérateurs, ils nous permettent également d' introduire une certaine abstraction. Voici donc un autre exemple. Voici donc une classe d'articles. C'est une classe de données figée. J'en ai parlé au début du cours. Et chaque article a un prix et une quantité. C'est le prix total, ça renvoie un entier, et c'est simplement le prix multiplié par la quantité. Et puis la fonction f for imprime les totaux qui obtiennent des éléments. Et je vois que je ne lui transmets pas une liste de rubriques et que je lui transmets un itérable de lignes et de principes. La seule chose que je ferais, c'est qu' en utilisant la boucle pour les objets et un prince, le prix total de ma fonction principale, j'ai une liste de rubriques. Regardez ça ici, puis je vais appeler les totaux imprimés. Donc, lorsque je l'exécute, il imprime simplement tous les totaux. Mais ce qui est bien maintenant, c'est que Print Totals attend quelque chose d'itérable, peu importe qu'il s'agisse d'une liste, d'un tuple ou de quoi que ce soit d'autre. Donc, par exemple, ici, si mes éléments de ligne sont listés, je peux les remplacer par un tuple, comme ceci. Maintenant, ce n'est plus une liste, mais l'impression des totaux ne compte pas. Tant qu'il est itérable, il peut faire son travail. Les itérateurs vous permettent donc d'introduire également une certaine abstraction, car Imprime Altos ne se soucie pas de la structure des données. Il se soucie simplement d' avoir quelque chose sur lequel il peut itérer et c'est tout ce dont il a besoin. 18. Iterators 3/3: Si vous voulez vraiment faire passer les itérateurs au niveau supérieur, vous pouvez également utiliser les outils GitHub, qui sont un package, package standard de Python doté de mécanismes d' itération très puissants. C'est une sorte d' algèbre d'itérations. Comme vous pouvez le faire, tous ces itérateurs, combinez-les de différentes manières pour obtenir un comportement vraiment complexe. Supposons par exemple que vous vouliez d'abord filtrer les éléments d'une liste, puis multiplier ces éléments par une autre valeur d'une autre liste, puis les enchaîner avec un autre ensemble de valeurs. Vous utiliseriez peut-être normalement une combinaison de fonctions et de boucles pour cela. Mais vous pouvez également utiliser d'autres outils pour combiner ces opérations en une seule opération de grande envergure à l'aide de l'algèbre itératrice. Je vais vous montrer quelques exemples de la façon dont cela fonctionne. Donc, pour ne pas les utiliser, les outils, bien sûr, il va falloir les importer. Ça ira. Et puis il y a deux choses que vous pouvez faire. Cela semble très simple, mais il y a quelques choses très avancées que vous pouvez faire avec les itérateurs. Je vais donc recommencer avec ma liste d'inventaire, car elle sera utile pour vous montrer ce que vous pouvez faire avec les itérateurs. Je vais simplement supprimer ces lignes ici. Eh bien, commençons par quelque chose de très simple. Un exemple très simple est count, une fonction d'itertools qui vous permet de compter à partir d'un certain nombre. Nous pouvons donc utiliser une boucle car c'est un itérable, n'est-ce pas ? Nous avons des dénombrements et nous pouvons ensuite indiquer, par exemple, le point de départ. Nous voulons donc commencer à compter à dix. Et vous pouvez même indiquer une étape, par exemple avec des étapes de cinq et imprimer I. Maintenant, si je m'arrête ici, cela se poursuivra essentiellement indéfiniment. Donc, si le chi est égal, disons à 50, alors nous allons faire une pause. Donc, quand je lance ça, c'est ce que tu obtiens. C'est donc la fonction count, counts Iterable. répétition n'est pas un exemple simple. Alors maintenant, cela va se répéter 105 fois. Exécutons ceci et vous verrez que c'est exactement ce qui se passe. Une autre chose que vous pouvez faire est d'accumuler, ce qui permet de calculer les sommes partielles. Supposons donc que nous ayons des sous-totaux , soit, disons, une liste de quelques nombres. Je tape juste des choses au hasard ici, comme ça. Ensuite, ce que nous pouvons faire, c'est utiliser accumuler. Et nous allons lui fournir la liste des sous-totaux. Mais vous pouvez également le fournir, en gros n'importe quel autre itérable gros n'importe quel autre itérable pour lequel vous pourriez utiliser un autre It's Tools, des fonctions, puis je vais simplement imprimer I et ceci dont nous n'avons pas besoin dans ce cas. Donc, ce que nous allons faire maintenant, c'est parcourir cette liste de sous-totaux et à chaque fois calculer la somme partielle, ainsi de suite. C'est ce que nous obtenons en conséquence. D'autres choses que vous pouvez en faire s'installent. Disons que nous avons des cartes à jouer, qui sont une liste, disons, de chaînes de caractères. J'utilise le copilote GitHub ici pour le générer pour moi afin de ne pas l'avoir saisi. Mais maintenant, vous pouvez utiliser des permutations. Les permutations fonctionnent. Ce sont les outils de toutes ces cartes à jouer. Et disons que nous voulons avoir toutes les permutations de, c'est tout pour les cartes à jouer. Et ensuite, imprimons-les. Comme les fermentations se situent à nouveau sur son ribosome, vous pouvez utiliser une boucle for pour itérer dessus. Ils vont partir. Et quand on lance ça, eh bien, c'est ce que l'on obtient. Nous avons donc maintenant toutes les combinaisons possibles de quatre cartes à jouer différentes. Et simplifions-nous un peu les choses pour qu' il soit un peu plus facile de voir ce qui se passe. Je vais donc simplement créer un a, un B et un C. Supposons que nous voulions avoir toutes les combinaisons de deux. Et puis c'est ce que nous obtenons, non ? Vous voyez donc que l'ordre est vraiment important ici. Donc AB est autre chose que ba, si l'ordre n'a pas d'importance, vous n'utilisez pas de permutations, mais vous utilisez des combinaisons, alors voici ce que nous obtenons. Bien sûr, il existe beaucoup moins de combinaisons de ces trois caractères, AB, AC et BC, au lieu d'une boucle pour imprimer chaque valeur, nous pouvons également utiliser autre chose. Nous pouvons utiliser l'initialiseur de liste pour transformer les résultats de ces combinaisons itérables en une liste que nous pouvons ensuite simplement imprimer et voici ce que nous obtenons. Il y a d'autres choses que vous pouvez faire avec des outils, par exemple utiliser une chaîne. Donc, si nous modifions les valeurs avec, disons, un analyste d , e, f, alors nous obtiendrons une seule liste qui est une chaîne de ces deux listes distinctes. Et bien sûr, vous pouvez transmettre n'importe quel type d'itérable ici. Une autre chose qui est également utile est le filtre faux. Vous pouvez donc imprimer, disons, une liste de It's a tool start, filter false. Et je veux filtrer tous les articles pesant moins de 1 kg. Je vais donc utiliser ici une fonction lambda où x point wait pour écrire correctement est inférieur à un. Et bien sûr, je vais lui transmettre mon inventaire. Et puis il devrait y avoir deux colonnes ici. Je pense que non, il ne me manque aucune parenthèse. Donc, quand je lance ça, c'est ce que nous obtenons. Nous voyons donc que nous n' avons que l'ordinateur portable, le livre et l'appareil photo, qui pèsent un kilo ou plus. Enfin, je veux vous montrer une carte des étoiles, qui est une autre fonction d'itertools qui vous permet de prendre une liste ou un itérable de tuples, dans ce cas de valeurs multiples. Ensuite, pour chaque valeur vous pouvez appliquer une sorte d'opérations. Je suis donc en train de faire une multiplication. J'ai donc une liste de tuples ici. Cela va donc créer une nouvelle liste de deux fois 68 fois 4,5 fois trois. Et c'est le résultat que vous voyez ici. C'est donc une carte des étoiles. Et maintenant, nous pouvons imaginer qu' avec ces deux fonctions, vous pouvez réellement combiner les choses de différentes manières. Vous pouvez donc utiliser le filtre false pour créer un nouvel itérable avec un sous-ensemble d' éléments et de liste. Et si vous utilisez les accumulations pour calculer le poids total ou quelque chose comme ça, vous pouvez utiliser la carte des étoiles pour calculer les temps d'attente , la quantité, etc. Vous pouvez utiliser toutes ces combinaisons pour créer une sorte d'algèbre qui leur donne un comportement complexe. Et c'est une façon différente de procéder que, disons, en utilisant des boucles ou en divisant des choses, des fonctions et des choses comme ça. Et vous pouvez bien sûr également créer vos propres itérateurs personnalisés qui répondent à vos besoins pour les combiner parfaitement avec itertools car tout suit le protocole itérable. Voici donc un petit exercice pour vous. Examinez votre code précédent et voyez si vous pouvez trouver des exemples dans lesquels vous pourriez, au lieu d'utiliser une boucle for pour parcourir la liste, utiliser les outils pour effectuer cette opération particulière. C'est vraiment amusant à faire et cela peut parfois conduire à un code beaucoup plus court. Mais attention, car si vous utilisez une combinaison d'outils très complexe, elle sera également très difficile à comprendre. Vous devez donc vous assurer que votre code est toujours lisible. Et bien sûr, vous pouvez toujours bien diviser les choses en différentes fonctions, même si vous combinez différentes fonctions d'outils. Dans la leçon suivante, je vais aborder les itérateurs paresseux, également appelés générateurs. 19. Générateurs 1/4: Dans cette leçon, je vais parler générateurs et de certaines fonctionnalités spéciales en Python : les données créent ce que l' on appelle un itérateur paresseux et ceux-ci ont été introduits et Pepper 255. Alors, que signifie réellement un itérateur paresseux ? Eh bien, c'est presque la même chose qu' un itérateur normal, sauf qu'il ne crée les valeurs que lorsque vous les demandez. Donc, au lieu d'avoir, disons que vous avez une liste avec des valeurs, vous définissez la liste avant de pouvoir la parcourir. Vous devez donc créer la liste complète. Avec un itérateur paresseux. Vous ne créez ces objets qu'au fur et à mesure que vous les parcourez. Cela signifie donc que l'itérateur paresseux ne stocke pas son concept en mémoire. Il crée le contenu à la volée lorsque vous le demandez. Cela signifie que dans certains cas, c'est une solution plus appropriée que de tout calculer avance avant de commencer itérer. Elle génère également un moyen simple de créer des itérateurs, car elle génère essentiellement une classe avec les méthodes iter et next dunder sur lesquelles vous pouvez ensuite itérer au lieu d' avoir à écrire toutes ces choses vous-même. Et comment faites-vous cela ? Eh bien, vous écrivez simplement une fonction, comme vous écririez une fonction normale, sauf que les moules utilisent une instruction return pour renvoyer une valeur, mais vous utilisez yield, return et yields renvoient une sorte de valeur, sauf que return met fin à la fonction. Rendements. Il enregistre l'état de la fonction tel qu'il est actuellement et renvoie la valeur. Ensuite, la prochaine fois que vous appellerez la fonction, elle récupérera simplement cet état et reprendra là où elle s'était arrêtée. 20. Générateurs 2/4: J'ai ici un exemple très simple de fonction de générateur. Vous voyez donc également que le type de retour est un générateur et que je parlerai de ce que ces choses font dans une minute. Mais c'est très simple. Nous avons une chaîne et nous donnons la valeur de cette chaîne. C'est donc la première fois que nous l'appelons. Mais ensuite, nous ajoutons un point d' exclamation et nous le cédons à nouveau. Cela crée un itérateur que vous pouvez appeler deux fois avant que la course ne doive arrêter l'itération. Et puis, dans la fonction principale, j'utilise for-loop pour parcourir l'itérateur que ce simple générateur nous fournit. Ensuite, j' imprime la chaîne. Vous voyez donc ici quel est le résultat de cette opération. Vous l'utilisez donc comme un itérateur normal sauf que ce code n'est exécuté que lorsque vous appelez la méthode suivante pour la deuxième fois. Alors, quel est exactement ce type ? Eh bien, cela dégénère le type, vous pouvez importer depuis la saisie, et cela nous indique quelle est la valeur de rendement. Vous pouvez donc voir que c'est en fait une chaîne. Et ce que cela signifie alors que vous disposez réellement d'un mécanisme d' envoi d'informations pour générer une fonction, puis que ces informations sont réutilisées pour le cycle suivant. Voici un exemple tiré de la documentation Python qui montre comment cela fonctionne. C'est un peu avancé, mais s'il s'agit d'un cours Python de niveau supérieur, alors pourquoi pas ? Mais en gros, ce qui se passe ici, c'est que nous stockons le résultat de l'expression yield, qui est ce que nous avons envoyé à cette fonction. Et c'est du type float. Ensuite, pendant que nous obtenons une valeur en utilisant le centre, nous allons en renvoyer la version arrondie, qui est un entier, puis la dernière, qui est la valeur de retour. Vous pouvez donc réellement combiner le rendement et le rendement dans un générateur et c'est à ce moment-là que la fonction s'arrête et qu'elle reviendra. D'accord ? Donc, quand je l'exécute, vous pouvez voir que j'ai ici une fonction principale où je l'appelle ensuite. Ensuite, je lui envoie ces valeurs. Ensuite, vous pouvez voir que cela passe par ces choses et que cela se termine par : OK, c'est essentiellement comme ça que cela fonctionne. Donc, un autre cas d'utilisation réel pour cela. Eh bien, pas beaucoup, pour être honnête, vous en aurez peut-être un, mais je n' ai jamais eu besoin de l'utiliser. Soyez également prudent lorsque vous combinez les rendements et les rendements. De cette façon, je pense que cela complique les choses, qu'il est plus difficile de comprendre ce qui se passe réellement. 21. Générateurs 3/4: La prochaine chose que je veux vous montrer on appelle des expressions génératrices. Et c'est aussi très puissant. Cela vous permet de créer une expression qui est en fait un générateur et de spécifier le calcul immédiatement dans l'expression. C'est un peu comme les fonctions lambda, les fonctions anonymes, mais ensuite ce sont des générateurs anonymes. Vous pouvez voir un exemple ici. J'ai un générateur de courant continu. Quand je passe la souris sur cette valeur, c'est qu'il s'agit en fait d'un générateur, mais amusant et une expression entre parenthèses, c'est l'expression du générateur. Et l'expression est deux à la puissance de I pour I, dans une fourchette de dix. C'est donc un générateur limité. Ensuite, j'utilise une boucle for pour itérer sur ce générateur de puissances, puis imprimer les générateurs de valeurs, tout comme les entiers, les flottants ou les fonctions sont des objets que vous pouvez transmettre à d'autres fonctions, par exemple la fonction somme accepte un générateur et donc aussi une expression de générateur. Vous pouvez donc très facilement créer la somme de toutes ces choses en passant simplement à la fonction somme. Donc, quand je lance ça, c'est ce que nous obtenons. La somme est de 1023. Les expressions génératrices sont également très puissantes car elles permettent d'effectuer de tels calculs, mais uniquement lorsque vous avez réellement besoin de valoriser. C'est donc différent de, disons, une compréhension par liste. Si je modifiais ces paramètres par des crochets, nous aurions une compréhension de la liste. Vous pouvez également répéter cela, mais la compréhension de la liste est déjà calculée lorsque vous la définissez en tant que générateur. Cela se fait donc paresseusement, ce qui est très utile si vous souhaitez économiser du temps de calcul. 22. Générateurs 4/4: Un autre avantage des générateurs est qu' ils s'intègrent bien au code simultané. C'est l'une des leçons précédentes dont j'ai parlé sur le code asynchrone, les dont j'ai parlé sur le code asynchrone, E/S et le code simultané. Eh bien, en fait, vous pouvez également avoir des générateurs de concurrence asynchrones. Voici un exemple. J' ai une fonction ici. C'est une fonction asynchrone qui obtient un nom de Pokémon aléatoire. Il est donc basé sur l' exemple Async IO que j'ai utilisé précédemment. Et cela renvoie simplement le nom du Pokémon. Et puis j'ai ici une fonction génératrice qui s' appelle next Pokemon après total. Ensuite, je fais une boucle où je passe en revue le total et chaque fois que j'utilise un poids pour obtenir le nom aléatoire du Pokémon , puis je donne ce nom. Vous pouvez également utiliser Yield Away. Vous n'avez donc pas besoin de varier ici. Mais comme vous pouvez le constater, il s'intègre très bien au code asynchrone. Vous écrivez simplement asynchrone devant et vous pouvez utiliser un poids dans votre générateur, puis ce sera simultané. Le type est cependant différent. Il existe un async qui génère un type comme vous le voyez ici. Mais en principe, l'idée est que cela fonctionne de la même manière. Et puis, si vous regardez la fonction principale, qui est également synchrone, nous avons une boucle asynchrone qui passe par le générateur de Pokémon suivant et obtient les noms des Pokémon suivants. Et vous pouvez utiliser des générateurs asynchrones différentes manières et Python. Par exemple, j'ai ici une liste de compréhension qui utilise le prochain générateur Pokemon asynchrone. Ensuite, j'utilise une compréhension de liste asynchrone pour obtenir toutes ces données. Donc, quand je l'exécuterai, vous verrez qu'il passe désormais par ces appels d'API et obtient tous ces noms de Pokémon. Cela ne rassemble pas toutes les réponses car c'est un générateur, donc c'est paresseux. Il n'exécutera la commande que lorsque vous la demanderez. C'est pourquoi nous les voyons apparaître un par un. Mais cela signifie que si vous n'avez besoin que de cinq noms supplémentaires, vous ne l'appelez que cinq fois, ce qui ne représente que cinq demandes d'API. Au lieu de faire toutes les demandes d'API et de ne prendre que cinq valeurs. C'est l'une des différences entre les indices de type du générateur et la génération asynchrone d'un type. Et j'ai dû corriger cela il y a une minute parce que c'était faux car l'asynchrone généré n'a pas le type de valeur de retour, car ce n'est pas possible avec l'asynchrone, nous n'avons que des rendements. C'est pourquoi il n'a que deux arguments au lieu de trois. Mais encore une fois, ce n'est pas quelque chose que vous utiliseriez normalement beaucoup dans votre code. Alors pourquoi est-ce utile ? Eh bien, il existe un moyen simple de créer des itérateurs sans avoir à créer de classe avec méthodes iter et next dunder. Bien entendu, ils s'intègrent également bien aux enfants ou aux outils dont il a été question dans la leçon précédente, économisent la mémoire et évitent des calculs inutiles. Si vous ne demandez pas la valeur, elle n'est pas calculée. Et en général, c'est un excellent moyen de représenter, par exemple, des flux de données sur un réseau. Chaque fois que des flux de données sur un réseau vous recevez un élément suivant depuis le réseau, vous devez faire attention au fait que générateurs peuvent couche plus difficile à comprendre, en particulier si vous commencez à combiner les instructions yield et return dans un seul générateur. Ensuite, étant donné que le code n'est exécuté que sur demande, il est possible que vous ne rencontriez une erreur qu'après un certain temps, ce qui pourrait entraîner une boîte inattendue et plus tard Vous devez donc vous assurer que vous les testez correctement. Donc, dans l'ensemble, les générateurs sont de très bons outils, ne les utilisent peut-être pas tout le temps, mais dans certains cas, ils sont vraiment utiles. Passons maintenant à la dernière leçon sur les gestionnaires de contextes. 23. Gestionnaires de contexte 1/4: La dernière fonctionnalité Python que je souhaite aborder dans ce cours est ce que l'on appelle le gestionnaire de contexte. Et cela s'appuie sur d'autres fonctionnalités dont j'ai parlé dans les leçons précédentes, telles que les itérateurs et les générateurs. Et il est également compatible avec le code asynchrone, comme je vais vous le montrer dans une minute, les contextes les gestionnaires sont vraiment utiles car ils vous permettent de contrôler ce qui se passe lorsque vous créez, détruisez, détruisez une ressource. Et vous pouvez vous assurer que, par exemple s'il y a une exception ou s'il existe une autre raison ou s'il existe une autre raison pour laquelle le programme doit arrêter de faire ce qu'il fait, vous pouvez utiliser un gestionnaire de contexte pour contrôler ce qui se passe afin de libérer une ressource. Cela est utile, par exemple, si vous devez fermer un fichier, si vous devez fermer la connexion à la base car vous devez faire remarquer à une autre surface que votre application arrête une tâche et vous voulez vous assurer que cela se produit toujours. C'est là que les gestionnaires de contextes sont vraiment utiles. C'est dans l'une des leçons précédentes que je vous ai montré comment ouvrir un fichier à l'aide de l'instruction width. Il s'agit en fait d'un exemple de gestionnaire de contexte. Et la raison pour laquelle nous utilisons une instruction de largeur est qu' elle permet au fichier Context Manager, Context Manager, de se fermer correctement une fois que vous avez fini de lire le contenu. Et il existe deux méthodes de Dahmer, encore une fois, qui sont importantes. Il y a les méthodes d'entrée et de sortie dominantes. Enter est l'endroit où vous placez tout ce qui doit se passer lorsque vous créez une ressource et sortez chaque fois que vous devez détruire la ressource. 24. Gestionnaires de contexte 2/4: Voici un autre exemple d'utilisation d'un gestionnaire de contexte. J'utilise SQL Lite Three ici, cela se connecte à une base de données qui n'est qu'un fichier local. Ensuite, je sélectionne des éléments à partir d'une table de blocs. Et vous voyez qu'ici, nous créons simplement une connexion avec des connexions à points sqlite, mais vous pouvez en fait l'utiliser comme gestionnaire de contexte. Lorsque je lance ce code , voici ce que nous voyons. Vous voyez donc que nous obtenons essentiellement une liste de blogs. Mais le fait est que nous devons nous assurer de toujours fermer la connexion, n' est-ce pas ? C'est donc ce qui se passe ici. C'est pourquoi il ne s'agit pas d'un blocage final. Donc, si je fais par exemple une faute de frappe ici, alors des blogs qui n'existent pas. Nous allons donc avoir une sorte d'erreur qui ne figure pas dans le tableau. Cela permet de s'assurer que la connexion est correctement fermée. Maintenant, si vous voulez éviter d'avoir à écrire ceci, essayez enfin, qui peut également être fait en utilisant sqlite point connect comme gestionnaire de contexte. écrivons donc simplement la largeur sqlite point connect en tant que collection. Et puis, bien sûr, je dois le mettre en retrait et il devrait y avoir une colonne ici. Ce que je peux faire maintenant, c'est faire la même chose, imprimer les blogs, mais ensuite je peux introduire une erreur. Mais la seule chose est que vous pouvez maintenant voir que dans le journal, cela ne ferme pas correctement la connexion. Ceci est principalement utilisé pour annuler les transactions dans la base de données, etc. Ce qui est bien avec Python, c'est que nous pouvons créer nos propres gestionnaires de contextes. Nous devons simplement fournir une classe dotée d'une méthode dunder d'entrée et de sortie , puis l'utiliser à la place. Vous en voyez donc un exemple. J'ai créé une classe sqlite. Je lui fournis le nom de fichier, donc c'est l'application de TB. Et je stocke une nouvelle connexion pour connecter à la base de données dans la méthode enter, puis j'obtiens le curseur puis la sortie. Je ne valide pas les modifications, puis je ferme la connexion. Donc, dans notre fonction principale, nous avons avec SQL light. J'utilise donc maintenant ce gestionnaire de contexte ici, qui va me donner le curseur, puis je pourrai exécuter ma requête et renvoyer le résultat. Donc, quand je l'exécuterai, nous obtiendrons à nouveau exactement les mêmes résultats, n'est-ce pas ? Nous allons imprimer ces blogs, mais ensuite ils appelleront « répondre » et sortir » une fois que tout sera terminé. Nous sommes donc sûrs que la connexion est toujours fermée, car maintenant, par exemple permettez-moi de présenter à nouveau une erreur. Si je le lance à nouveau, vous verrez qu'il a toujours appelé Entrée et Sortie. Le gestionnaire de contexte a réussi à fermer correctement la connexion, même en cas d'erreur. 25. Gestionnaires de contexte 3/4: Maintenant, au lieu de cette classe avec des méthodes d'entrée et de sortie, vous pouvez également utiliser un décorateur qui s'appuie sur la génération d'une fonction évoquée dans la leçon précédente. Voilà à quoi ça ressemble. J'importe le décorateur du gestionnaire de contexte à partir de contextes en direct et c'est amusant de le faire ici pour indiquer que cette fonction va être un gestionnaire de contexte. Et puis, vous voyez, j'utilise une structure de générateur avec rendement pour définir réellement ce qui doit se passer dans les parties réponse et sortie. Donc, la façon dont cela fonctionne, c'est que tout ce qui précède les rendements est la pièce maîtresse. Tout ce qui suit est la partie de sortie. Donc, c'est essentiellement ce que vous voyez ici. Et cela a exactement le même effet que l'utilisation d'une classe. Ou si je lance ceci, vous voyez que nous obtenons une connexion qui se ferme ici, qu'une connexion se crée et que nous imprimons les blogs. Si je supprime à nouveau ici, retirons un autre personnage juste pour le fun. Et puis réexécutons-le. Vous voyez, nous avons toujours cette erreur, mais maintenant elle ferme correctement la connexion car nous utilisons un gestionnaire de contexte, un décorateur. 26. Gestionnaires de contexte 4/4: La dernière chose que je veux vous montrer est que les gestionnaires de contexte prennent également en charge la syntaxe asynchrone et attend de l' intégration du code simultané, tout comme les générateurs, si elle souhaite accorder un gestionnaire de contexte asynchrone, utilisaient le décorateur asynchrone du gestionnaire de contexte. Maintenant, il y a quelques problèmes de frappe ici, car il s'agit d'un exemple plus approximatif. Mais l'idée est que vous utilisez dans ce cas générateur asynchrone au lieu d' un générateur synchrone normal. Les gestionnaires de contextes travaillent donc également dans ce sens. Donc, par exemple, supposons que vous ayez une couche de base de données asynchrone. Vous pouvez utiliser la syntaxe asynchrone await pour y accéder, par exemple , la connexion à la base de données, nous utilisons la connexion et publication est également asynchrone et nous avons placé l'async devant. Ensuite, vous pouvez l'utiliser dans le reste de votre code, comme je le fais ici, par exemple, je reçois tous les utilisateurs. Sql light lui-même n'est pas asynchrone, mais il existe un package appelé sclerites qui est asynchrone que vous pouvez utiliser pour accéder à une base de données SQL Light de manière asynchrone. Vous voyez un exemple simple de la façon dont cela fonctionne. Donc, au lieu de sqlite point connect, je le fais, je connecte tous sqlite point connect. Mais c'est asynchrone, tout en utilisant les instructions de largeur. Et vous faites la même chose pour un curseur récupère toutes les données de la table. Donc, lorsque vous l'utilisez, eh bien, les endroits les plus importants où vous devez vous assurer bien fermer ou de nettoyer votre désordre, même en cas de problème. Et c'est particulièrement le cas des bases de données dont nous assurons le suivi des connexions. Ou vous voulez vous assurer de fermer cette connexion. Ou peut-être devez-vous laisser un nœud d'API indiquer que vous avez terminé une sorte de processus, vous voulez vous assurer que même si une exception se produit, cet appel final se produit toujours. Et c'est là que les gestionnaires de contexte sont vraiment utiles. Enfin, du point de vue de la conception logicielle, il est vraiment intéressant de pouvoir regrouper la création et destruction de ressources en un seul endroit. 27. Conclusion: Merci beaucoup d'avoir suivi ce cours. J'espère que cela vous a donné matière à réflexion et vous a donné quelques idées sur la façon d'améliorer votre code Python existant. J'ai eu beaucoup de plaisir à enregistrer ce cours, mais il y a bien sûr une tonne d' autres choses dans lesquelles nous pourrions nous plonger. Pour en savoir plus sur Python, en particulier sur la conception de logiciels, comme je l'ai mentionné au début, consultez ma chaîne YouTube, youtube.com slash ion codes. Si vous avez des questions ou des suggestions, écrivez simplement un commentaire ici. J'adorerais avoir de tes nouvelles. Merci d'avoir regardé et prenez soin de vous.