Session sur les modules, paquets et imports
Session du 25 septembre 2024 à 21h00
Développement Web & Frameworks
DevOps & Environnement
Librairie Standard & Modules
Deviens membre Premium
Cette session de mentorat est réservée aux membres Premium. Rejoignez-nous pour accéder à toutes les rediffusions des sessions de mentorat !
Premium
- +100h de formations
- +180 exercices de code
- +100h de mentorats en rediffusion
- 20 projets
- Mentorats groupés hebdomadaires
- Support individuel avec nos mentors
Session sur les modules, paquets et imports
Discussions sur CookieCutter et la résolution d'un problème d'encodage avec Windows. Explications et discussions autour de django-components pour créer des composants dans un projet Django. Pour finir, présentation de la gestion des modules et du rôle important joué par les modules spéciaux __init__.py et __main__.py.
00:00:00 :Bonjour à tous, aujourd'hui c'est un mentorat d'une demi-heure, l'idée c'est de pouvoirrépondre à vos différentes questions dans un premier temps et si vous n'avez pas dequestions, si vous n'avez rien de précis à discuter, je vais de mon côté préparerun sujet qui est la notion de paquet ou de package de module et d'import en Python qui
00:00:30 :est souvent très peu discuté finalement dans les tutos parce qu'on pense que c'est évidentmais dans les projets complexes en fait il y a toujours des drames par rapport à ça,soit on est bloqué parce qu'on ne sait pas comment importer, soit on se retrouve aveceffectivement des essais erreurs, fructueux ou infructueux et pour la petite histoire
00:00:55 :l'année dernière on a recruté des développeurs Python au travail où j'étais et si on s'étaitbasé sur la question qui portait sur les imports on aurait dû pratiquement refusertous les candidats vu que sur la question en question il n'y a personne qui a réussià importer le projet. C'est pour dire qu'il y a un système en Python qui est relativement
00:01:18 :simple mais que si on ne l'a pas compris on peut vite être dans les choux et ça c'estéventuellement quelque chose qui vaut la peine d'être discuté. Donc voilà. Donc aujourd'hui
00:01:29 :foire aux questions c'est vous d'abord qui venez avec vos questions, avec vos envies dediscussion et s'il n'y a personne qui a d'idées moi j'arrive avec mon sujet. Donc n'hésitez
00:01:42 :pas à prendre la parole si vous avez quelque chose qui dans la semaine vous a posé problème,quelque chose sur laquelle vous avez travaillé et que vous n'avez pas bien assimilé ou sivous avez un problème particulier à discuter sinon on ira sur l'autre sujet.
00:01:57 :Moi je voulais dire juste que grâce à ton intervention cet après-midi j'ai réussi àutiliser ton cookie cutter Django settings. Oui. Donc il marche bien même sous Windows,
00:02:13 :bravo et merci. Voilà c'était moi qui a effectivement, que je l'avais fait,j'avais fait pour ma communauté et je ne l'avais pas testé et en fait c'est intéressant de voirce qu'il se passe. Finalement je peux le montrer, finalement ce qui posait problème vu que ça a
00:02:28 :été discuté dans le channel mentora. Ici je vais monter le coup, on va aller là et puis on va allerdirectement sur le GitHub en question. Donc ça c'est le projet, finalement de savoir comment ça
00:02:51 :fonctionne ce template, c'est pas le sujet du jour, mais ce qui posait problème et ça ça peutêtre quelque chose qui est intéressant pour vous, c'est dans tous les endroits où je vais manipuleret écrire des choses dans des fichiers. Donc là c'est un template qui génère des projets Django.
00:03:09 :Et ce que j'ai rajouté c'est typiquement dans les open, des choses comme ça où je force l'encodageà UTF-8. Sur Mac et sur Linux, en fait l'encodage dans le terminal il est de toute manière UTF-8.
00:03:25 :Donc si on nommait cette option, c'est pas un problème, il va lire le fichier en considérantque c'est de l'UTF-8 et dans le monde Python, pratiquement tous les fichiers sont UTF-8. Mais
00:03:38 :quand on utilise ça dans un contexte Windows, d'ailleurs en l'occurrence que ce soit Gitbashou PowerShell c'est pareil, on a par défaut un encodage qui est un dérivé de Windows 1256ou quelque chose comme ça, qui est le CP des poussières, je sais plus le numéro, mais c'estun dérivé du latin 1, donc un encodage des caractères sur 256 bits. Et pour le coup c'est
00:04:11 :pas de l'UTF-8. Donc il y a plein de caractères qui ne peuvent pas être encodés et c'est ce quiposait effectivement problème. Donc ça c'est une première chose. Donc si on veut quelque chose de
00:04:21 :compatible avec, si on ne met pas ça en coding, en fait c'est le système qui dicte l'encodage quisera l'encodage par défaut. Si on force dans tous les opens l'encodage à UTF-8, alors là il va
00:04:33 :utiliser l'encodage qui est forcé. Ça c'est une première chose. Une deuxième chose qui posaitproblème, c'est si vous avez à copier des répertoires sur Windows, il y a des droits depriorité par rapport à, si vous avez plusieurs programmes, plusieurs threads, plusieurs partiesde votre programme qui accèdent et qui essayent de manipuler le même fichier ou de manipuler le
00:04:57 :même répertoire, la logique n'est pas tout à fait comme sur Linux ou sur macOS et c'est des chosesqui peuvent poser problème. Donc en l'occurrence pour le problème de Simon, c'était un problème
00:05:06 :d'encodage, donc merci, sans toi je ne l'aurais pas détecté parce que pas forcément testé surWindows. Pour les autres, c'est un outil que j'avais mis à disposition pour ceux qui font du
00:05:25 :Django, dont le but était de produire des settings de production que j'ai commenté demanière abondante en français pour montrer comment sur un projet Django, séparer laconfiguration de développement de la configuration de production et puis deux, comment avoir uneconfiguration de production relativement sécurisée en tout cas et commenter en français pour qu'on
00:05:55 :puisse simplement comprendre un petit peu pourquoi on utilise ces settings là et donc c'est ce queSimon a essayé d'installer cet après-midi et du coup il n'a pas pu le faire cet après-midi,il l'a fait ce soir, on verra si ça l'aide ou pas. N'hésitez pas si vous avez d'autres questions.
00:06:14 :En fait, le premier n'est pas pour moi une question, j'avais rencontré un problème cetaprès-midi sur Django Components et je suis rentré sur le webinaire que tu avais organisé en questionde me ressourcer un peu. J'avais remarqué que tu n'avais pas parlé de fichiers CSS. Du coup,
00:06:44 :j'ai continué mes recherches là-dessus, je suis tombé sur une vidéo de Bigbits qui parlait deDjango Components et là j'ai dû ajouter une classe média et ensuite ajouter un gabaritindépendance CSS si je ne me trompe pas et ça fonctionne mieux maintenant. Alors ça,
00:07:10 :si on regarde Django Components pour les autres, c'est un paquet qui, que vous faites du web,permet de décomposer l'interface en composants. Alors c'est un des paquets parmi d'autres qui
00:07:25 :permet de le faire. Et si je vais dans leur doc, leur doc sera mieux accessible si je vais sur leurGitHub. Ici donc, si tu lis simplement leur readme, il y a des choses qui ont changé depuis
00:07:46 :le webinaire en particulier, ils ont sorti leur version 0.100, mais des choses qui sont plusvalides. Le problème c'est que c'est encore quelque chose en développement donc il y a
00:07:54 :éventuellement des choses qui sont appelées à changer. Mais ce dont tu parles, c'est effectivementla manière de définir des composants, ça se fait via des classes bidon et je scrolle pour trouver lepoint, voilà. Voilà typiquement en composant. Et puis ce qu'on va faire dans ce cas là, c'est
00:08:13 :effectivement avec cette classe média, déclarer notre fichier CSS. Alors typiquement on va,avec ces trucs de composants, on va définir un composant calendrier par exemple qui va,si vous voulez ajouter sur votre page web, un calendrier. Donc il y aura un fichier Python,
00:08:30 :ça c'est celui où on va déclarer la classe qui est là. Et puis on pourra éventuellement mettreen script CSS, en script JS et puis notre code HTML. Donc en fait tous les fichiers. Et les fichiers
00:08:45 :CSS et JS qui sont déclarés dans cette classe média qui est à l'intérieur de la classecalendar. Et à partir de là, quand on se retrouve dans notre projet Django, on a la possibilité
00:08:57 :d'ajouter avec ce tag Component CSS Dependencies, ici ce code là va ajouter dans le head de la pagetoutes les dépendances CSS. Et ce tag en fin de fichier juste avant le body ici, va ajouter
00:09:12 :toutes les dépendances CSS de tous les composants qu'on a ajouté dans cette page. Ici dans l'exemplemicroscopique qui est disponible, nous avons ajouté qu'en composant calendrier, donc icion va ajouter juste le JS du calendrier et le CSS du calendrier. Effectivement dans mon cas,
00:09:29 :c'est très rare finalement que j'ajoute comme ça du, alors du JS c'est moins rare, d'encore que,mais du CSS c'est rare. Et particulièrement ici, dans le webinaire j'utilisais, sauf erreur,
00:09:43 :Tailwind ou pas Tailwind, mais ces temps j'utilise beaucoup Tailwind CSS qui permet de styler laplupart de notre page, souvent avec des classes qu'on va ajouter directement dans l'HTML. Et pour
00:09:54 :le coup, il y a très peu de CSS qui devient spécifique aux composants, puisque le CSS dansles composants, en fait il est dans simplement les classes qu'on ajoute ou balise directementdans l'HTML. Et du coup, en ce qui me concerne, dans les composants, c'est très rare que j'aie
00:10:13 :besoin d'écrire du CSS spécifique. Mais si on veut écrire du CSS spécifique, on peut effectivementici avoir un composant qui réunit à la fois le template, à la fois les styles et à la foisles JS. Et puis on peut le faire pour chaque élément qu'on va retrouver sur une page web,
00:10:34 :et ensuite créer une page web devient finalement une histoire de Lego,d'imbrication et d'agencement de différents composants sur le sein de la page.Donc là c'est pour Django Components. Donc effectivement,
00:10:48 :bonne trouvaille, tu peux effectivement avoir les trois types de fichiers en même temps.J'ai une question là-dessus. En utilisant Django Components,on n'aura pas de problème sur la performance des applications web?
00:11:04 :Alors techniquement, ça fait multiplier les petits templates. D'un autre côté,sur un vrai projet également, on multiplie les templates aussi avec des inputs finalement,des choses comme ça. Donc finalement, c'est une manière de rationaliser
00:11:23 :ça et de s'organiser plus facilement. Après, il y a tout un système de cache dans Django.Donc la plupart du temps, ces différents templates sont assemblés une fois et ensuite mis en cache,parce que des grandes parties de la page sont des parties constantes de la page,c'est-à-dire qu'elles ne vont pas varier en fonction de l'utilisateur qui les demande,
00:11:47 :et certaines parties vont varier un petit peu. Donc en fait, pour un utilisateur donné,on peut le mettre en cache la plupart du temps. Et donc, avec ces bibliothèques de composants,
00:11:59 :mais Django Components en particulier, gère également tout seul en cache,ce qui fait qu'on a un peu de pénalité de performance par rapport à ce qu'on feraiten Django. A savoir que si je fais du Django classique, on va dire, donc sans composants,
00:12:15 :j'ai mes pages et puis je compose toutes mes pages en entier, je fais quand même malgré toutde l'héritage de template, je fais de l'inclusion de template, etc. Donc je dirais que quelque part,
00:12:26 :c'est pas des coups neutres ça non plus. Donc l'un dans l'autre, que j'utilise ou queje n'utilise pas Django Components, dans les deux cas, je vais utiliser la génération detemplate et en pratique, ce qu'on montre, c'est des sites complets qui sont faits par exempleavec Django et HTMX et qui sont faits complètement avec les templates Django. En pratique, lors du
00:12:48 :premier chargement, ils sont plus rapides que des sites React ou autres. Donc pour le coup,le problème de performance n'est pas évident, en tout cas par rapport à la concurrence.
00:12:59 :Alors c'est clair que par rapport à un site complètement statique, c'est-à-dire un sitestatique, c'est qu'on aurait complètement généré le code des pages de manière statique une foiset puis après on sert juste du HTML. C'est clair que c'est plus lent, mais là il n'y a pas de
00:13:17 :miracle. Donc par rapport à un générateur de site statique, ce sera plus lent, mais un générateurde site statique, pour le coup, on n'est pas dynamique. Donc si on fait un site statique
00:13:28 :avec par exemple un framework comme Astro ou Hugo ou des trucs comme ça, même ajouter unsystème de commentaires sur son site devient quelque chose qui n'est pas une mince affaireparce que du coup c'est statique et il n'y a pas derrière un langage back-end qui permetd'alimenter dynamiquement le contenu du site en fonction de ce que veut faire l'utilisateur.
00:13:49 :Donc le prix à payer pour avoir un site dynamique, c'est de pouvoir jouer un petit peusur ou avec le moteur de template de Django. Si on utilise Django comme moteur de template,
00:14:02 :ceux qui font du React ou du Vue, qui jouent avec un framework front-end, ils ont exactement le mêmeproblème, donc imbrication de composants et au final ça fait un peu zoomer. Donc ici je dirais
00:14:18 :il y a une pénalité de performance, oui. Est-ce qu'elle est acceptable ? La plupart du temps oui.Si elle n'est pas acceptable localement, ça veut dire qu'il faut optimiser et joueréventuellement avec le framework de cache de Django. C'est vrai qu'il y a quand même beaucoup
00:14:33 :de choses. Quand on apprend Django au départ, ça a l'air relativement simple dans les tutos,mais il y a beaucoup de choses dont on ne parle pas. Cache framework Django. Donc effectivement
00:14:49 :Django a un framework pour vérer le cache, soit en utilisant la base de données, soit en utilisantdes bases de données alternatives comme Memcache ou bien Redis. Donc il y a quelques informations
00:15:00 :dans la doc en principe. Et en Django, on peut se servir du cache dans les templates, par exemplejustement pour pallier ces effets d'inclusion de template, de découpons composants, etc. On peut
00:15:12 :faire du cache également au niveau de la base de données et de l'ORM pour éviter des recherches enbase de données inutiles, etc. Donc à plusieurs endroits au niveau des vues, des templates et des
00:15:25 :modèles, on peut jouer avec le cache. Et ça, je dirais que c'est un sujet qui vient généralementaprès qu'on ait bien pris en main Django. Mais c'est un vrai sujet parce qu'effectivement,
00:15:39 :on se rend compte qu'on veut déployer son premier vrai projet qui a plein de chosesauxquelles on n'a pas pensé de ce point de vue. Donc la question est tout à fait pertinente.
00:15:48 :D'accord, merci beaucoup. C'est plus clair ainsi.Après, on trouve, c'est un petit peu le défaut du contenu sur Python, sur Django.C'est qu'il y a énormément de sujets, de tutos pour débutants. Et il y a quelques développeurs
00:16:16 :qui publient des choses très avancées parfois. Mais entre les deux mondes, c'est-à-dire entrele post-débutant et puis l'expert, il y a une sorte de no man's land où il y a quelquespublications intéressantes. Peut-être là, il y a la possibilité de faire un petit peu mieux,
00:16:34 :puis d'essayer de vulgariser ces sujets-là un petit peu plus. Est-ce qu'il y a d'autres questions?Moi, je veux bien reposer juste une petite question sur Cutty Cutter.
00:16:51 :Oui.En fait, je me demandais si cet outil, c'était un outil qui était utile uniquement pour bienconfigurer un projet au début. Ou est-ce que c'est un outil qui peut être utile quand on
00:17:06 :travaille à plusieurs sur un projet et qu'on intègre des développeurs au fur et à mesurepour qu'ils prennent en main plus facilement le projet?Alors, c'est clair que d'utiliser Cutty Cutter, il faut un petit peu avoir toujours une mêmepratique. On va finalement obtenir du code, une structure qui est identique ou similaire.
00:17:33 :En fait, au boulot, nous, on ne l'utilise pas que pour générer le projet de départ. Par exemple,même si je veux générer un paquet Django, c'est-à-dire un répertoire au sein de mon projetavec une certaine structure, on a différents Cutty Cutter pour ce genre de choses. En particulier,
00:17:54 :comme au boulot, on fait du Django. On n'utilise jamais, par exemple, Django Startup,Python Management Builder dans mon startup, qui permet de générer une app au sein de son code.
00:18:10 :Simplement parce qu'on a certaines pratiques où on va structurer les choses et quand on a Djangoqui nous génère cette app, il y a plein de choses qu'on doit faire à la main quand même et on perdun petit peu de temps. Par contre, on a aussi l'avantage, c'est qu'on travaille avec Django.
00:18:25 :Donc, on a eu de travailler avec Flask qu'on a stoppé il y a cinq ans complètement parce quejustement, dans les projets Flask ou Fast API, etc., c'est framework qui laisse beaucoup de
00:18:38 :liberté à l'utilisateur. C'était un gros problème effectivement pour l'équipe dans laquelle jetravaille parce qu'on est dans une université et dans cette université, on a beaucoup de tournus.
00:18:49 :On travaille avec des jeunes ingénieurs qui restent une année, une année et demie, deux ans,et puis après ils partent, puis il y en a d'autres qui viennent, etc. Donc, en fait,
00:18:56 :on a énormément de tournus et ce qu'on voit, c'est qu'avec Flask, il y a des choses qui donnentbeaucoup de liberté du point de vue de l'architecture. On doit toujours finalement faire
00:19:10 :de l'onboarding et accueillir les gens et leur expliquer complètement l'architecture. Tandisque Django, il a tout en sept de bonnes pratiques dont on prend conscience déjà dans les premierstutos qu'on fait. Donc, en fait, on apprend très vite qu'on va architecturer les choses d'une
00:19:29 :certaine manière. On va dans toutes ces apps ou tous ces répertoires de son projet, on aurapartout en Models.py, on va mettre des classes de modèles. Donc, pour ceux qui ne savent pas,
00:19:40 :les classes de modèles sont une interface entre notre site web et la base de données. Et on saitqu'on aura un module qui s'appellera Models.py la plupart du temps et qui va accueillir ces modèles.
00:19:56 :Je n'ai pas besoin de me poser la question de savoir comment je vais architecturer le truc.Par contre, effectivement, il y a des choses qu'on ne fait pas exactement, qu'on fait en plus de ceque fait le générateur de code par défaut de Django. Donc, dans ce contexte-là, on utilise
00:20:09 :Cookiecutter. Et puis, moi, j'utilise aussi Cookiecutter pour plein de choses qui n'ontrien à voir avec Django, voire des choses qui n'ont même rien à voir avec la programmation.
00:20:17 :Donc, si tu te trouves à devoir générer quelque chose qui est composé de plusieurs fichiers ouplusieurs répertoires même, avec une structure bien définie, mais en même temps que tu veux lapersonnaliser à Cookiecutter, tu peux poser des questions à l'utilisateur sur ce qu'il veutfaire. Et après, tu peux générer un projet de démarrage en tenant compte de ces réponses-là.
00:20:44 :Donc, dès qu'une personne a besoin de créer plusieurs fichiers, plusieurs répertoires avecces fichiers, ces répertoires, ça ne peut pas juste être en copie-collée, ça doit êtrequelque chose qui va quand même remplacer des valeurs à différents endroits. Le faire
00:21:01 :avec un générateur de template comme ça, tu évites beaucoup d'erreurs. Parce que moi,je me souviens de l'époque où je configurais mes projets Django même à la main. C'est
00:21:14 :pas que tu ne sais pas faire, mais simplement, si tu sais que tu démarres un projet et quela première journée, elle va être consacrée complètement à la configuration, tu as potentiellementplein d'erreurs et tu passes ta première journée à débugger des petites choses vraimentà la con jusqu'à ce que tu aies quelque chose. Donc, ça doit plutôt déculpabiliser,
00:21:40 :de voir que même après 15 ans, quand tu démarres un projet et que tu as une cinquantainede fichiers à écrire à droite à gauche, tu fais des erreurs à la con et ça te prenddeux jours pour le débugger. Donc, en cela, c'est un outil qui rend service.
00:21:55 :Ok, merci beaucoup.Je veux bien t'entendre sur ce que tu avais prévu de nous raconter sur les imports.Voilà, on va y aller. Je ne veux pas, j'attendais pas que je ne vous le présente et que je ne
00:22:18 :vais pas vous couper la parole.Voilà, donc ici, au niveau des imports, déjà ce qu'il faut savoir, c'est qu'il y a touten tuto officiel de bidon que finalement assez peu de débutants ont lu en entier.
00:22:45 :Je crois que sur les dernières statistiques, l'année passée, j'ai dû avoir environ unecentaine d'étudiants en accompagnement individuel et quand ils sont arrivés chez moi, je penseprobablement 90 voire 95 de ces 100 n'avaient pas lu le tuto officiel, par contre, avaientvu pratiquement toutes les vidéos YouTube qu'ils avaient pu sur Python. Donc, dans ce
00:23:09 :tuto officiel, qui est d'extrême qualité, vous avez tout en chapitre, le chapitre 6,qui est dédié aux modules d'une part et aux paquets et aux imports et comment ça fonctionne.
00:23:21 :Donc, n'hésitez pas à aller voir et c'est un petit peu de ça que je vais vous parleraujourd'hui. Donc, le module, c'est peut-être la chose qu'on a le plus conscience quand on
00:23:31 :débute en Python. Le module, c'est le fichier .py, donc c'est un fichier contenant les définitions,les instructions. Tout notre code Python va dans les modules. C'est le fichier qui a l'extension
00:23:41 :.py. Le vocabulaire correct, c'est pas un fichier, c'est un module au sens de Python.Donc ici, n'importe quel fichier, ici, n'importe quel élément avec une extension .py sera notre
00:23:54 :module. Ça, c'est le premier niveau d'organisation au niveau de Python. Et puis, le deuxième niveau,c'est les paquets. Les paquets, c'est des regroupements de modules. Donc, c'est un
00:24:05 :répertoire qui contient des modules et ce répertoire doit obligatoirement contenirun init.py pour être un paquet traditionnel. Si on ne met ce fichier, ça en fait un certain
00:24:18 :type de paquet qui a des effets de bord, qui est un petit peu embêtant parce que la plupart desgens, ils disent, c'est pas nécessaire de mettre ce init.py. Oui, c'est obligatoire et si on ne
00:24:26 :le met pas, on a justement quelques effets qui peuvent être embêtants. Un paquet, c'est unrépertoire qui contient plusieurs modules et qui contient en particulier un module spécial quis'appelle __init__.py, un petit peu comme la méthode init que vous avez dans les classes
00:24:43 :en Python. Donc, en fait, en Python, ce init là, c'est quelque chose qui va contenir du coded'initialisation. Mais dans le cas des paquets, même s'il est vide, il est obligatoire. Ça,
00:24:59 :c'est une première chose. Et éventuellement, on peut y mettre du code d'initialisation.Donc, ça nous donne un petit peu quelque chose comme ça. Donc, si j'ai un projet comme j'ai ici,
00:25:12 :je pourrais très bien avoir à la racine de ce projet un module avec l'extension .py et puis jepourrais avoir un répertoire qui contient d'autres modules qui seront groupés justement au sein dupaquet. Et ici, ce répertoire est un paquet au sens de Python parce qu'il contient ce fichier
00:25:33 :init.py. Ce fichier init sera systématiquement exécuté par Python lorsque j'importe soit lerépertoire. Donc, on peut en Python importer un répertoire. Simplement, depuis ce module,
00:25:48 :je fais importe mon paquet, ça va importer ce répertoire. Qu'est-ce que ça veut direimporter un répertoire ? En fait, ça veut dire exécuter son init. C'est ce qui va se passer. Et
00:26:01 :en même temps, si j'importe module 1, ça va aussi exécuter le init ou si j'importe module 2,ça va aussi importer le init. Donc, le init ici, c'est un module qui est automatiquement exécuté
00:26:13 :dès que j'importe quelque chose qui est situé dans ce paquet-là. Donc, je peux, par exemple,typiquement y mettre du code qui doit absolument être exécuté avant module 1 ou avant module 2,si jamais j'utilise ces modules. Moi, je n'ai jamais compris ce qu'on pouvait avoir intérêt à
00:26:31 :mettre dans ce init. Est-ce que tu aurais un exemple simple ? Alors, typiquement dans mesprojets Django, Jean-Méan, est-ce que toi, tu fais du Django ? Je n'ai pas vu qui avait parlé.
00:26:46 :Ah oui, donc si tu as salé mon setting tout à l'heure, tu fais du Django. Ça répond à maquestion. Donc, oui, par exemple dans un projet Django. Alors, regardons, j'en ai peut-être un
00:27:00 :ou j'ai un exemple ici. Prenons le pas dans celui-là, peut-être dans celui-là. Alors,je n'ai pas d'exemple ici, mais on peut en voir, on peut ici en ajouter un. Donc, par exemple,
00:27:24 :dans le fichier qui contient mon settings.py, donc le répertoire de configuration de Django.Par exemple, donc ce répertoire de configuration, dès que je lance une commande en Django,n'importe quoi, par exemple, si je lance une commande python-manage.py, server, etc. En fait,
00:27:43 :ce que n'importe quelle commande va faire, c'est qu'elle va aller lire mon fichier deconfiguration Django. Donc, si une commande doit importer ce fichier-là pour qu'il soit lu,
00:27:56 :alors il va importer ce fichier qui est situé dans ce package, et donc ici, dans ce unit,on peut voir des choses. OK, une première chose. Dans des gros projets comme celui-là, ce qu'on
00:28:11 :fait, c'est qu'on utilise souvent des variables d'environnement pour configurer le projet. Etces variables d'environnement, on les met souvent dans un fichier qui s'appelle .env à la racine
00:28:24 :du projet. OK, dans ce fichier .env, je peux avoir différentes configurations, comme databaseURL, donc c'est souvent une variable qui va définir les données de connexion à ma basede données. Je vais mettre dans une variable d'environnement parce que je n'ai pas envie de
00:28:44 :pousser ça sur GitHub. Donc, en fait, dans ces variables d'environnement, je vais mettre toutce qui doit rester secret, mes clés d'API, par exemple, ou si je fais des paiements avecStripe API Key, typiquement, je vais définir une clé pour utiliser l'API de Stripe, par exemple,et je vais la mettre typiquement dans ce point. Vous voyez qu'il est gris ici parce qu'il est
00:29:09 :listé dans le fichier .gitignore qui va ignorer simplement ce fichier. Donc je ne vais pas lepousser sur GitHub parce que dans ce fichier, je mets des choses inutiles. Malgré tout,
00:29:20 :le fait que je définisse des configurations dans ce fichier font qu'automatiquement j'aimeraisque toutes ces variables soient lues lorsqu'on arrive, lorsqu'on configure et on lance le projet.
00:29:33 :Comme de toute manière, ce répertoire de configuration est importé ou on importe versle settings.py via les commandes ici, alors éventuellement, ce init, c'est un bon endroit
00:29:46 :pour mettre du code qui va aller lire ça. Alors typiquement, sur un projet comme celui-là,je peux installer un paquet qui est spécialisé, par exemple, pour aller lire,par exemple, un paquet comme Django Environ qui est spécialisé pour aller lire ce genre de chose.
00:30:04 :Et puis, pour le coup, si je veux être sûr que quoi que je fasse en Django, ce fichier est lu,par exemple, moi je le mets dans le init ici. Alors je vais importer ici Environ et puis je
00:30:17 :vais aller importer aussi. Ici, from passlib import pass. Techniquement, je vais répéter unpetit peu de code qui est dans le settings. Finalement, ça, moi j'ai l'habitude de le
00:30:39 :définir plutôt ici pour le coup. Et voilà, je peux du coup aller lire. Donc on va créer unenvironnement avec la classe Environne.env. Et puis ensuite, env.read.env. Et puis là je vais
00:30:57 :aller lui donner l'endroit où aller lire ce fichier, donc base.dir. Et puis on va aller lirele fichier .env. Donc typiquement, le fait de placer ça dans un répertoire de configuration
00:31:16 :dont je sais qu'il sera forcément lu, où on va forcément au démarrage de Django importer deschoses qui viennent d'ici, m'assure que ce code sera pratiquement systématiquement la premièrechose que Django fera quand il veut travailler. Et ça, ça m'évite d'aller mettre ce morceau de
00:31:37 :code dans le manage.py ici, en haut. Je pourrais imaginer de le mettre en haut. Et le problème,c'est que si je le mets là, ça, ça va juste configurer mon projet pour les commandes que jelance au terminal, comme manage.py, par exemple, pour un serveur, etc. Donc pour ces commandes-là,
00:31:56 :si je mets au manage.py, c'est bon. Mais si je vais sur un serveur, c'est ce fichier .wsgi quisera exécuté en premier. Donc si je suis sur serveur, je devrais mettre ce code que je viens
00:32:07 :de mettre ici. Et puis si je suis en train de lancer des commandes, je vais le mettre ici.Mais dans tous les cas, si je le mets ici, il est exécuté par manage.py, il est exécuté par
00:32:17 :.wsgi.py, il est exécuté par .sgi.py. Donc finalement, on a une sorte d'endroit, en passageobligé au sein de notre projet, où forcément, ce fichier sera un des tout premiers fichiers àêtre exécuté. Donc si je prends mon mini projet ici, voilà. Si on peut imaginer que ce module-là,
00:32:41 :la racine, c'est juste un code de démarrage, et que ces modules-là seront soit des fichiersde config, soit des modules qui font des choses, on est pratiquement sûr que ce unit,sera forcément un des tout premiers fichiers Python qui sera exécuté. Pour le coup,
00:32:59 :si j'ai besoin d'avoir du code, et d'être sûr que ce code soit exécuté avant tout le reste,c'est un super endroit pour le mettre. Donc ce fichier, ce module peut rester vide,
00:33:12 :mais il peut contenir du code qui doit absolument être exécuté avant les autres modules. Comme ça,même si on importe un module comme module 1, il y aura automatiquement unit qui va s'exécuteravant de toute manière. Donc je sais que si j'ai du code qui doit être exécuté avant module 1,
00:33:32 :ou avant module 2, mais je ne sais pas si je vais appeler module 1 ou module 2 avant,finalement je sors de module 1, je sors de module 2, mais je vais le mettre dans le unit,comme ça je n'ai pas besoin de le dupliquer dans les deux modules. Donc ça c'est le premier...
00:33:47 :Est-ce qu'il est exécuté qu'une seule fois, ou est-ce qu'il sera lu à chaque fois ?Non, le code Python, il ne s'exécute qu'une fois dans un programme. Donc le code qui est à l'intérieur
00:33:55 :d'un module .py est chaque fois exécuté qu'une seule fois dans le cycle d'exécution d'un programme Python.Donc il n'y a aucun risque qu'il soit exécuté une deuxième fois. Python va voir qu'il a déjà exécuté
00:34:11 :ce code, je vois qu'il y a quelqu'un qui est rentré. Ah, il y a une main qui est levée.J'ai vu que tu avais levé la main, et puis tu pourras poser la question juste après.
00:34:22 :Et donc il sera exécuté de toute manière qu'une fois. La deuxième fois, Python va vouloir l'exécuter,puis il va voir, non celui-là je l'ai déjà exécuté, donc je ne l'exécute pas une deuxième fois.
00:34:35 :J'ai un exemple encore qui peut être sympa que je vais vous montrer, mais il y avait une question justement.Donc quelle était la question ? Alors ? Oui ? En fait c'était toujours sur l'init, l'exécution du init en fait.
00:34:51 :Oui. Bon, c'est H. Disons que je fais, j'importe module 1 dans mon module, par exemple,le fichier module 1 dans mon module. Est-ce qu'à chaque fois que mon module est lancé,
00:35:10 :il va appeler le init pour exécuter le module 1 ? Non, il va l'exécuter qu'une fois.On peut voir ça. Donc je vous encourage à faire des petites expériences de votre côté.
00:35:23 :Pour faire une petite expérience, on va regarder quel type de petites expériences on peut faire.Donc ici, quelle expérience on peut faire ?Donc ici, mon module et puis mon paquet. Dans mon paquet, on va mettre un init. Dans ce init, je vais mettre un print.
00:36:15 :Dans mon paquet init, je vais le copier là. Et puis on va mettre mon module 1. Alors ici, dans mon module.Et puis, mon module 2. Donc ici, si dans mon paquet, je fais alors ici, par exemple, mon paquet importe.
00:37:07 :Mon module 1 et puis mon module 2. Donc je les importe les deux. Exécutons ça. Ce qu'on voit, c'est que j'importe ici mon module.Donc comme j'importe mon module 1, la première chose qu'il fait, c'est qu'il exécute le code qu'il y a dans init ici. C'est pour ça qu'on le voit en tout premier dans mon paquet init.
00:38:29 :Donc, exécuter plusieurs fois un même paquet ne réexécute pas le code du paquet en Python. Jamais.Merci. Donc, il y a une sorte de cache, une fois qu'il l'a exécuté une fois. C'est ça. Il y a une variable, je ne sais pas si on peut la voir ici.
00:39:06 :Ce n'est pas une variable qu'on regarde très souvent, mais je crois qu'il y a un truc qui s'appelle les modules, quelque chose comme ça.Ce n'est pas un module, il faudrait que je regarde une variable cachée qui liste tous les modules qui ont déjà été exécutés.
00:39:43 :Et si oui, il ne va pas le réexécuter. Donc, chaque module qui est exécuté, il va l'enregistrer dans un répertoire.En fait, le code qui est dans ce module va être conservé et c'est le même code, c'est le même résultat qui va envoyer les mêmes objets.
00:40:03 :Donc, ce module va contenir des fonctions, des variables, des classes, etc. Tout ça, c'est des objets.Et pour le coup, une fois qu'il a été exécuté, Python va créer ces objets. Et puis, quand je les réimporte, Python va chaque fois redonner les mêmes objets.
00:40:22 :Donc, c'est pour ça que finalement, on n'a jamais cette réexécution.Si j'exécute 2 fois, ici, par exemple, si je définis dans mon module 1 une fonction,ici, une fonction qui ne fait rien, et si je l'importe 2 fois,je l'ai mis dans mon paquet 2, le 1, oui.
00:40:54 :Alors, mon module 1, mon paquet, mon module 1, importe f.Et puis là, mon paquet, mon module 1, importe f, on va le renommer f2, par exemple.
00:41:16 :Vu que je teste, je fais un print, f1 is f2, je vois qu'effectivement, là, il n'a pas créé 2 fois la même fonction,et puis, on voit que cette fonction, c'est simplement la même qui a été réimportée.
00:41:36 :Donc, la première fois, il a importé le code, et puis, la deuxième fois, il ne réimporte pas le code.Si je l'importe ici, etc.Donc, Python est relativement intelligent pour pouvoir faire les choses 2 fois.
00:41:50 :Ok, donc ça, ce init, c'est une sorte de point d'entrée dans un répertoirequi vous permet de mettre du code qui sera exécuté une fois.
00:42:01 :C'est également quelque chose de très utile dans la pratique, par exemple, il arrive très souvent,Alors, de nouveau, si vous faites du Django, simplement, c'est applicable à plein d'autres contextes.
00:42:16 :Si je prends un paquet exemple, et puis, je mets un init, on va procéder de la même manière.On a un fichier, on met une .py, et puis, mettons que vous avez, si vous faites un MVC,
00:42:35 :la semaine passée, on a parlé de MVC, donc Models.py, je crée des modèles.Et puis, dans ces modèles là, j'aurai mon modèle 1, une classe modèle 1, et puis, une classe modèle 2,et puis, il y aura beaucoup de classes de modèles, et puis, au bout d'un moment,je commence à avoir marre parce que j'ai trois kilomètres de classes et du code dans ce fichier modèle,
00:42:59 :et quand je commence à avoir des milliers de lignes dans ce fichier modèle, ça devient ingérable.Imaginons qu'entre deux, j'importe ces modèles.Donc ici, from Models, Models, import modèle 1, par exemple, et modèle 2.
00:43:21 :Donc, un jour ou l'autre, je vais dire qu'il commence à y avoir trop de code là-dedans,pour juste le mettre dans un module Python.Et ça, c'est également une possibilité que j'ai, c'est qu'à un moment donné,je peux simplement créer un répertoire qui s'appelle Models.
00:43:38 :Dans ce répertoire, je mets en unit.py.Je peux mettre ce fichier ici, et puis je peux le dupliquer.Par exemple, modèle 1, et puis modèle 2.
00:43:59 :Alors, dans le modèle 1, on va garder la classe modèle 1, par exemple.Elle est vide, donc ça ne fait pas de sens de faire ça.
00:44:08 :Dans l'autre, je vais garder la classe modèle 2.Et dans le unit, je peux faire en from.model1, on va y revenir sur le point tout de suite,
00:44:20 :import modèle 1, et from.model2, import modèle 2.Voilà.En cours de route, je vais donc changer ce Models de Models.py en un répertoire Models,dans lequel il y a plusieurs modules qui contiennent chacun une classe, etc.
00:44:46 :C'est une manière, au bout d'un moment, lorsque mon code commence à gonfler,je peux transformer un module en un paquet,et puis j'importe les différentes classes ensuite dans mon unit.
00:45:01 :Ce qui permet, dans mon main, par exemple, ici, ou dans n'importe quel fichier qui importait,ça nous permet de fonctionner quand même.C'est-à-dire que si je fais en from.models, import modèle, il importe effectivement la classe modèle 1
00:45:15 :qui a été importée dans le unit.Sinon, ça ne fonctionnerait pas, parce que sinon je devrais aller chercher dans mon codetous les endroits où j'ai importé Models, ici,et puis je devrais faire en from.models.model1, import modèle 1,
00:45:37 :et puis je devrais faire en from.models.model2, import modèle 2.Mais en fait, le fait que j'ai le unit ici, dans lequel j'ai fait cet import,me permet de garder tous les imports que j'avais avant de transformer mon unit.
00:46:01 :Donc je peux garder simplement les imports que j'avais avant, ça fonctionne.Donc quand je fais cette transformation-là,finalement je n'impacte pas du tout les modules ou autres qui importaient déjà des choses de mes modèles.
00:46:17 :Et cette situation, vous l'avez dans un projet Django.Par exemple, si je prends une application blog, par exemple,j'utilise le répertoire, et puis à l'intérieur, je mets en unit.
00:46:36 :Et puis, vous voyez que dans une application Django classique,vous avez un modèle, vous avez des vues, vous avez des managers,vous avez des formulaires, des managers, des factories, etc.
00:47:00 :Donc vous avez plusieurs modules comme ça,et puis quand vous commencez à développer votre application, votre site,vous allez ajouter des choses, des fonctions, des classes en vues,vous allez ajouter des classes en modèles,vous allez ajouter des classes en managers, des classes en forms, etc.
00:47:17 :Et puis au bout d'un moment, il y en aura beaucoup à l'intérieur,alors ça peut être une bonne idée de créer une nouvelle app,mais je pense est-il qu'ici, à un moment donné, si il y a trop de vues,je peux créer un répertoire vues avec un unit à l'intérieur,
00:47:36 :et puis aller mettre mes différents modules de vues ici, etc.et puis commencer à découper le code dans plusieurs fichiers.L'avantage, c'est que si je fais des imports de tout ça,je n'aurai pas besoin de changer les imports dans le reste de mon projet.
00:47:55 :Ça, c'est une deuxième application de ce unit.Donc voilà, ce unit, c'est un point d'entrée uniquequi me permet de faire des choses avant tous les autres modules,qui me permet d'importer les classes de ces différents modulespour que le reste du code n'y voie que du feu,et l'impression que là, j'étais en fichier,
00:48:17 :mais en fait, finalement, j'ai transformé mon fichier initial en un paquet,et c'est pour ça que c'est très utile d'avoir ces paquets qui ont un unit à l'intérieur,parce qu'on peut finalement travailler avec ça,comme si c'était un module,alors qu'on va pouvoir splitter le code dans plusieurs fichiers,
00:48:36 :dans plusieurs modules,et donc on va pouvoir découper,avoir dans chaque module plutôt des fichiers de 500 lignes, 1000 lignes, que 3000 lignes,et de cette manière-là, ce sera beaucoup plus facile de naviguer dans votre projet,puisque vous allez pouvoir quelque part classer par thématique les différentes choses.
00:48:58 :Donc voilà le pourquoi.Donc le rôle de ce fichier init,c'est un répertoire qui contient plusieurs modules,et le rôle de ce point d'entrée ici,ça permet d'abord au répertoire d'être considéré par Python comme un paquet,sinon il n'est pas considéré comme ça,et les paquets permettent une organisation hiérarchique du code,
00:49:22 :et ce init permet d'exécuter du codeavant tous les éléments qui sont à l'intérieur de sa hiérarchie.Donc en fait, le code qui est exécuté dans le init,il est exécuté avant tous les modules qui sont à l'intérieur.
00:49:34 :Donc ça c'est un des deux fichiers spéciaux,alors là j'en ai déjà parlé dans mon exemple,je ne vais pas forcément revenir sur les imports maintenant,je vais passer ça,et puis on va voir un deuxième fichier spécial, c'est le main.py.
00:49:52 :Le main.py, en fait, dans notre exemple,je reviens, vous voyez toujours mon VS Code ?Oui, oui, c'est bon.Voilà, alors ici, souvent,alors ici plutôt que d'appeler les modèles, je vais l'appeler exemple,module 1, module 2,et puis module 3.
00:50:25 :Ok, et puis on a un main ici.Et puis dans ce main, on va voir, on va exécuter du code.On pourrait voir, on voit parfois,ou quand même assez souvent, ce genre de structure de projet.
00:50:53 :Et puis là, on a notre fichier, pardon, readme, etc.Donc on a du code comme ça,et puis si je veux lancer un tel projet,alors on va dire que notre code applicatif, il est là,on va faire lancer une fonction,une fonction, ma fonctionnalité,qui fait juste un print,
00:51:27 :ça fonctionne.Ok, donc ici, dans main, je peux importer,alors from example.module1,importe ma truc,et puis je pourrais exécuter ma fonctionnalité là.Voilà.Et donc voilà, on peut exécuter ce truc,donc exécuter ce projet ici,Python main, et puis ça permet de voir,modèle1, importe modèle1,mais bon, c'est pas ce que je veux faire,
00:52:21 :c'est dans le Unix que c'est toujours le cas,donc pour l'instant, je vais les guider.Voilà.Ok, ça fonctionne.Ok, maintenant, du point de vue application,d'appeler ce main,comme code de démarrage de l'application,main, c'est pas très descriptif de mon projet.
00:52:43 :Par exemple, ici,si j'ai un programme de jeu d'échecs,par exemple, je vais l'appeler chess,par exemple.Donc, pour lancer chess,je suis, j'appelle du coup main,c'est pas top,et puis du coup dans main,lgFranchiseModule1, moduleNodeFiles.
00:53:08 :Oui, mais c'est pas le cas.Est-ce que j'ai oublié de sauver ?Ah oui, pardon, j'ai oublié de sauver.Ok, donc ici,vous démarrez le programme de chess,mais en appelant main.
00:53:27 :Ouais, pas top.Donc, qu'est-ce que vous pouvez faire ?Vous pouvez déplacer ce fichier ici,vous le déplacez dans votre répertoire, ici.Vous renommez ça en main,avec deux underscores avant et après,et à partir de ça,vous avez ce main ici,vous pouvez également exécuter ce programme.
00:53:48 :Du coup, vous exécutez maintenant le répertoire.Vous exécutez le répertoire,et en fait, c'est le main derrièrequi va être exécuté.Sauf erreur, je pourrais,hop, ça je le fais jamais,mais je pourrais zipper,faire un zip de ça,et je pourrais encore exécuter ce zip.
00:54:10 :C'est une manière de packager un petit peu simple,mais, hop,est-ce que je peux compresser ?Compresse chess, voilà,donc je produis en zip,idon-mchess.zip
00:54:33 :Non, pas module, maisoui, un module spécial.Il y a une manière de le faire pour les zips,mais il faudra que je regarde.bidon,exécute,zip,non, c'est avec zipapp, pardon,hop,du zipapp,myapp,puis je dois définir le truc.
00:55:03 :Je regarderai ça,et puis je vous remonte,je vous ferai une démo une autre fois, effectivement,donc il faut utiliser le module zipapp,et puis après vous pouvez l'exécuter en zippant,et quand vous exécutez le code zippé,il va aller chercher ce module main ici.
00:55:17 :Voilà,ici le main,donc le main,c'est quelque part,c'est votre répertoire,c'est votre fichier de lancement,et du coup,il vous permet d'exécuter votre répertoirecontenant tous vos codes,comme si c'était un programme,et donc voilà son rôle.
00:55:41 :Et puis,ensuite,il permet également de faire icitous les imports qu'on aura à l'intérieur de ça.Maintenant,le fait que main soit partie du paquet,on peut commencer à transformer ces importsen imports relatifs,puisqu'on est à l'intérieur du paquet,on n'a aucun code à l'extérieur,donc il n'y a pas forcément besoin
00:56:08 :d'apporter chess à chaque foisqu'on est, par exemple,dans un module ici à l'intérieur.Donc ce que vous pouvez faire,quand vous êtes dans le paquet,vous pouvez faire des imports relatifs,donc enlever le nom du premier module ici,donc ce que je vais faire,c'est que j'importe depuis le même paquet,
00:56:23 :depuis module 1,etc.,une fonction.Donc ici,je fais un import relatif,un import qui commence avec un point.Et ça,vous voyez vraiment très souvent en Django,c'est la façon naturelle d'importerles modules en Django.
00:56:39 :Mais ça,ça pose des difficultés,parce que du coup,il faut savoir lancer le programme.Si vous lancez correctementun programme Python,normalement,vous le lancez avec l'option .m.
00:56:50 :Si vous le lancezsans l'option .m,il faut mettre un .py,mais là seulement,vous n'avez pas de .py,parce que c'est un répertoire,et là,a priori,ça ne fonctionne pas.
00:57:03 :Également,si vous allez lancer ou exécuterdes programmes,des fichiers,qui seraient à l'intérieurde ça,vous ne pouvez pas exécuterjs.main.py.Main.py,ça ne fonctionne pas.
00:57:22 :Donc,exécuter un programme Pythonavec,ici,un chemin absoluavec un .py à la fin,c'est vrai,ça peut être vraiment scabreux,ça ne fonctionne quequand vous avez un script,monofichier,etc.
00:57:40 :Donc,ici,typiquement,quand vous organisezles choses correctement,il faut lancer aussiles programmes correctement,et lancer un programmecorrectement en Python,c'est le faire comme ça,ou le lancer avec Python 3,si vous êtes sur Linux,ou alors,avec .py-m.main,
00:57:56 :si vous êtes,si vous êtes sur Windows.Donc,voilà pour,en fait,ces packages,et ces inputs,donc ça c'est le rôle du main,c'est de créer un fichierde lancement,un module de lancement.
00:58:13 :Comme il s'appelle déjà main,c'est franchement inutilede mettre cette protection,pour le coup,et on arrive avecquelque chose de relativement simple,ici.Donc,si on regarde un petit peula structureque je recommande pourun paquet,voilà.
00:58:35 :Pour un projet Python,on va dire qu'on a notre,la racine de notre projet,un readme,ensuite,un paquet pour votre projet,c'est le nom,avec le nom de votre projet,et puis c'est lui qui sera exécuté.
00:58:50 :Donc vous exécutez,le nom de votre paquet,l'exécution de ce paquet vaexécuter ce main,enfin il va exécutercet init d'abord,et le main ensuite.
00:59:00 :Puis dans ce main,on va typiquement importer des choses,du paquet 1,du paquet 2,et donc les initde ces paquets seront exécutéssi j'ai du code d'initialisationà l'intérieur.
00:59:13 :Mais ce que vous voyez,c'est qu'à l'intérieur de tousces paquets Python,ils ont tous en commund'avoir ce init.Donc gardez bien cette structure en tête,et gardez également bienle fait dedémarrer le programme,pas simplement avecun fichier .py,
00:59:31 :avec un chemin absoluà la fin,mais gardez vraiment en têted'exécuter tout programme Pythonavec l'option-met le nom de votre répertoirede projet,et ça, ça lancera correctementle code,et ça fera que tous les importsfonctionneront correctement,et qu'également Python sera capablede trouver très facilement
00:59:55 :vos fichiers de ressources,des images,des fichiers de données, etc.Également, si je veux lancerdirectement un modulequi est à l'intérieur de ma hiérarchie,donc si je reviens là,et typiquement je veux faire un test,par exemple,et je veux lancer ce module-là,je vais me positionnerà la racine de mon projet,
01:00:15 :et je vais typiquement fairece qu'on a ici,python-m, projet,.packet1, .module11, etc.Et là, vous avez donc la manièrequi marche, qui fonctionnera toujoursde démarrer un projetqui est composé de multiples paquetsqui organisent un grand nombre de modules.
01:00:38 :Et ça, c'est typiquement une question,je suis à peu près sûrque je peux organiser un recrutement,et si je veux être sûrque je n'ai pas le candidat super,en tout cas, je suis pratiquement certainque 9 personnes sur 10 se plantentau démarrage de ce petit programme-là.
01:00:59 :Et c'est quelque chose de très dommage,parce que finalement,quand on a compris comment ça fonctionnait,pour le coup, on ne va plus jamais galéreravec des imports dans toute sa vie.
01:01:13 :Même sur un méga projet Djangoqui aura une cinquantaine d'appsou une centaine d'apps,et parfois même des appsqui sont imbriquées les unes dans les autres,on n'a plus de problèmeà se repérer dans cette hiérarchie,à importer les choses correctement,à démarrer son programme correctement,ce qu'on est de problème d'import.
01:01:35 :Et donc, si vous êtes en mesurede comprendre ce petit exemple,vous serez en principe safe.Ok, moi je vais arrêter là,parce qu'on a fait une heure plus ou moins,mais je vais vous inviter,si vous voulez en savoir plus sur ça,il y a une main levée, il y a un bruit,
01:01:58 :s'il y a une question, il ne faut pas hésiter.C'est parce que je me suis trompé de bouton, pardon.Je voulais applaudir et j'ai juste appuyé sur la main.
01:02:06 :Il n'y a pas de problème.Pipon tutoriel.Pipon tutoriel, alors chez moi,il m'amène ça en premier,après 24 ans, 25 ans de Pipon,je fais encore, probablement,je leur parcours une fois par année,pas pour moi, mais déjà pour voirs'il y a des nouveautés,et pour pouvoir conseiller des ressources aux étudiants.
01:02:31 :Et une chose qu'il faut se dire,c'est que c'est la seule ressource du webpour laquelle vous pouvez vraiment faire quoi,en laquelle vous pouvez avoir confianceau sujet de Pipon.
01:02:45 :Toutes les autres partaient du principeque soit la personne qui parle être débutante,même si c'est moi,et partaient du principe que vous ne connaissez pascelui qui parle, vous ne savez pas s'il vous parled'une syntaxe qui est obsolète, etc.
01:03:02 :Mais, dans la doc de Pipon,vous avez plusieurs langues,vous avez les versions, si vous voulez voir le tutola version 3.2, même, je ne vois pas l'intérêt,
01:03:14 :mais on pourrait remonter et voir l'évolution de Pipon.Et vous avez plein de choses qu'on voitdans absolument aucun tuto,et également la notion de module et de paquettraité au chapitre 6,je crois que c'est probablement celui que je recommandele plus souvent aux personnes qui viennent vers moi
01:03:34 :en disant je m'arrête les cheveux sur un import,lié à ça. Effectivement, vous allez voir icile paquet, avec une architecturepar exemple de paquet ici, complexe,et la possibilité de voir les différentes possibilitésd'importer les choses, soit par des importsdits absolus,donc ici, on démarre tout depuis la racine,
01:03:58 :depuis sound, et puis on se tape tout le chemin,mais également les imports relatifs,et si vous faites du Django, vous connaissez ces imports relatifs,parce que c'est ce qui est souvent fait,from point import quelque chose, from point point import quelque chose,from point point filter import quelque chose,
01:04:14 :et c'est très pratique, mais si on n'a pas l'habitude,si on n'a pas l'habitude des projets avec de multiples fichiers,de multiples répertoires, ça peut vraimentêtre compliqué au début à lire,à comprendre, etc. Donc n'hésitez pas
01:04:29 :à regarder un petit peu cette question des moduleset des paquets, même si vous avez l'impression que finalementl'import c'est une partie, donc vous comprenez bien,n'hésitez pas à le faire, il est très bien traduit,et si vous avez des questions, je vous invite à les poser,soit ce soir, soit dans le
01:04:47 :channel Dockstring Mentora.Merci beaucoup Thierry, parce que moi effectivement je m'arracherégulièrement les cheveux avec les imports, et notammentavec le fameux petit point là dont tu parlais tout à l'heure,donc je vais aller lire cette documentation pourvoir si enfin je me sensplus en sécurité à chaque fois que je vais devoir importer
01:05:12 :un fichier dans un autre. Il faut vraiment se direavec l'import relatif, le petit point, c'est que tu regardesFrom Point, ça part du répertoiredans lequel se trouve ton module, et puis aprèsà partir de là, tu montesla chaîne de l'import jusqu'à ce que tu arrives au final
01:05:30 :à la classe, au module, ou à la fonctionque tu apportes, et finalement c'est relativementlogique. Je vais pas parler dansce Mentora court en principedes problèmes, j'avais fait des webinairesil y a pas mal de temps là dessus,où on voit en fonction de comment on démarre
01:05:51 :le programme, là j'ai juste parlé de comment le démarrer correctement,mais il y a d'autres problèmes, si on démarre pasle programme correctement, parfois on va se retrouveravec une origine pour les importsqui est différente de l'originepour les opens, pour les codesoù vous ouvrez des fichiers, et ça peut être une autre
01:06:12 :prise de tête, c'est que parfois vous essayezd'importer, vous avez réussi à importer votre truc,après vous essayez de faire une ouverture de fichiersoit pour y écrire, soit pour lire, et puis c'est pasle même répertoire de référence, et en faitil y a une logique là derrière, et effectivement il y a plein de scénarios
01:06:30 :possibles, où ce qu'on appelle lecurrent directory, le current working directory,le cwd, etla racinefinalement, où les fichiersqui sont, les répertoires pardon, qui sontlistés dans la liste 6.pass, qui est la liste
01:06:51 :qui contient tous les répertoires dans lesquels va chercher Pythonfinalement sont des endroitsdifférents. La manière de lancerle programme que je viens de vous montrer avant,en lançant la commande depuis la racine du projet,et en lançant le répertoiredu projet, le répertoire principal, qu'on appellerale paquet principal, avec
01:07:15 :l'option M, garantit qu'on ala racine du système d'importà la racine de votre projet, etla racine de l'ouverture des fichiers à la racine du projetau même endroit. Et donc, vous savez
01:07:30 :comme ça, que le référentiel, c'est là où vous avezle readme de votre projet, et puis vous n'avez qu'à remonterà chaque fois pour savoir comment aller importer n'importe quelfichier dans votre projet. De savoir où est le référentiel
01:07:42 :et puis de l'avoir bien à la racine de son projet, c'est vraimentquelque chose qui vous sauve la vie quand vous êtes bloqué.Et la bonne nouvelle,c'est que je n'ai jamais eu un importou un problème d'import d'un étudiant ou d'uncollègue qui venait vers moi, qui n'est pas résolu en 5
01:08:00 :minutes, parce qu'en généralquand on comprend le système et qu'on apprendvraiment comment il fonctionne,à ce moment-là, généralement les situations sont trèsvite débugées. Et vous investissez
01:08:15 :une heure de votre temps à essayer de comprendre ça,une heure de temps à m'écouter, puis après une heure supplémentaire à essayerde comprendre ça et à démêler les trucs, et après vous êtes tranquillepour le reste de votre vie.
01:08:27 :Bien.Ok.Donc là, il nous restejuste le temps de finalement se direau revoir avant d'aller se coucher, mais comme je vous l'ai dit, à votre disposition,ces prochains jours, ces prochaines semaines,si vous avez des problèmes spécifiques par rapport aux imports,si vous avez n'importe quel problème, mais si vous avez des problèmes spécifiques
01:08:51 :aux imports, c'est volontiers que j'y réponds.Et la lecture du chapitre 6 du tutorielest un super endroit pour ça.Et je vois qu'il y a une main levée.
01:09:03 :Oui, en fait,je demandais si un jour on pourrait voirles modules Ascensio.Oui, en fait,ça c'est une possibilité. Il faut nouveau voiren fonction des... J'ai pas encore le programme d'octobre.
01:09:21 :Thibault a pas encore donné le programme d'octobre.Donc je sais pas encore quels sontles modules que je donnerai. Probablement que je vais restersur les modules du mercrediou sur les modules un petit peu foire aux questions comme ça.
01:09:36 :Donc si je reste sur ces foires aux questions,c'est toujours ouvert et puis là on peut en parlerd'Ascensio.Est-ce qu'il y a d'autres?N'hésitez pas, d'ailleurs,si vous avez effectivement à l'approche d'une foire aux questions,si vous avez des questions spécifiqueset puis vous voudriez qu'on centrela foire aux questions vraiment sur cette thématique,
01:10:03 :je choisis en principe à chaque fois quand mêmeune thématique backup si personne n'a des questions.Donc si vous me remontez un sujetque vous aimeriez discuter,c'est probablement que je vais le faire.
Aucune occurrence trouvée pour « ».
Sources
- Tutoriel Python officiel sur les modules - à 00:23:00 dans la vidéo
00:00:00
Introduction et plan de la session
00:00:30
Problème d'import en Python
00:01:29
Déroulement de la session
00:01:59
Explication du problème d'encodage avec Cookiecutter
00:06:17
Discussion sur Django Components et CSS
00:16:50
Utilisation de Cookiecutter pour les projets Django
00:22:00
Introduction aux modules et aux imports en Python
00:26:27
Question de Simon : que mettre dans __init__ ?
00:34:43
Démonstration de l'exécution du fichier __init__
00:42:01
Transformation d'un module en paquet
00:49:50
Fichier spécial __main__.py
00:58:25
Organisation de projet et bonne pratique d'import
Bravo, tu es prêt à passer à la suite