Un nouveau tutoriel Python particulièrement complet

disponible sur developpez

a marqué ce sujet comme résolu.

Salut,

Je viens de m’apercevoir qu’un très gros tuto Python est sorti sur developpez.com, y’a une dizaine de jours, et m’a l’air original : ici

J’hésitais à le poster puisque ça fait un peu de la "pub à la concurrence", mais je me suis aussi dit que c’était bête de ne pas venir le partager et en discuter. Je sais qu’il y a pas mal d’adepte du python par ici, ça pourrait vous intéresser.

J’ai juste parcouru en diagonal pour le moment, et je n’y reviendrai que lorsque j’en aurai besoin.
J’ai été impressionné par le spectre balayé par le cours, ça part de qu’est-ce qu’une variable et comment la déclarer à la métaprogrammation. ça ne m’a pas l’air mal écrit, mais je laisse les fins connaisseurs discuter de la qualité.
De mon point de vue, il manque un petit chapitre sur l’écosystème autour de python, particulièrement pip, qui est un aspect assez attrayant, le tuto se concentre vraiment sur le langage lui-même, mais il me semble avoir tout d’une référence.

+0 -0

J’ai un peu survolé et j’ai quelques remarques en vrac de trucs qui m’interpellent.


Pas très grave, mais le style de l’affectation (sans espace autour de =) ne semble pas conforme PEP 8 et me paraît plutôt inhabituel en Python :

a=42  # style du cours
a = 42  # style plus habituel

Ça peut paraître négligeable, mais nous savons à quel point les pratiquants d’un langage (Python ou autre) peuvent être tatillons avec le style. D’ailleurs, ce n’est pas pour rien qu’on trouve de la valeur aux formateurs de code.


Je ne comprends pas pourquoi le tutoriel veut tout comparer avec le langage C dans les sections V-6 et V-7. Par ailleurs, l’analogie du match...case de Python avec le switch...case du C est potentiellement trompeuse, puisque Python fournit en fait du pattern matching au lieu d’une simple commutation traditionnelle. Je ne sais pas si cela a été écarté au début pour des raisons pédagogies, c’est possible.

Toujours dans la même section, on compare le C et Python ainsi :

L’instruction switch…case elle aussi très souvent utilisée dans d’autres langages n’existait pas jusqu’à Python version 3.10. Jusque là on pouvait programmer plus ou moins facilement son équivalent.

Équivalent d’un switch…case (différentes actions en fonction d’une valeur)…

# Python
{
    1: action1,
    2: action2,
    3: action3,
}.get(valeur, action_autre)()
/* C */
switch (valeur) {
    case 1: action1(); break;
    case 2: action2(); break;
    case 3: action3(); break;
    default: action_autre();
}

Personnellement, je n’ai jamais vu un tel code en Python pre-3.10.


On voit parfois le code Python commencer ainsi :

# coding: utf-8

Est-ce encore nécessaire en Python 3 moderne ? (vraie question, parce que je ne l’ai pas vu depuis l’ère de Python 2).

+0 -0

Oui, c’est vrai qu’il aurait dû se passer des parallèles avec le C
C’est quelqu’un qui vient du monde du C donc il a dû lui même apprendre en faisant ces parallèles, mais le cours s’appèle python de zéro
Le match lui a été remonté dans les commentaires, il répond qu’il l’a un peu ajouté au dernier moment et que ça mériterait effectivement plus de précision. Je suis d’accord que le pattern matching est quand même bien différent. Venant de C++ et m’orientant sur Rust, je suis aussi confronté à ce changement subtil mais permettant pas mal de nouvelles choses ^^

+0 -0

On voit parfois le code Python commencer ainsi :

# coding: utf-8

Est-ce encore nécessaire en Python 3 moderne ? (vraie question, parce que je ne l’ai pas vu depuis l’ère de Python 2).

sgble

Non, l’encodage par défaut de l’interpréteur python est passé à utf-8 avec python 3

+2 -0

Il y a quand même beaucoup d’approximations un peu partout. J’ai zappé sur plusieurs pages et à chaque fois il y avait un truc un peu douteux ou carrément faux.

Tiens par exemple là je suis sur le paragraphe introductif aux dictionnaires. Bon déjà, en 2022, c’est pas très utile d’encombrer le propos avec des considérations sur Python 2, a fortiori dans un document pour débutants. Il parle des vues en Python 3 vs Python 2 (différents noms), puis quelque mots sur .iterkeys() et companie qui sont des générateurs simples plutôt que des vues. Il dit ensuite que ces méthodes ont disparues en Python 3, sauf que… c’est pas tout à fait vrai. iter(some_dict) en Python 3 (qui appelle __iter__) fonctionne comme iterkeys() en Python 2 et a les mêmes limitations (une seule itération et non utilisable si on modifie le dict entre la création et l’exhaustion). Bref, il s’empêtre avec des détails sur Python 2 vs Python 3 qui sont pas très utiles, à propos de considérations relativement avancées (les générateurs sont bien plus loin dans le cours) qui les rendent peu pertinentes à ce stade, et en plus il se goure au passage.

Rien de tout ça n’est très grave, mais quand c’est un peu partout dans le tuto, c’est dommage… Cela dit, les tutos avec lesquels j’ai démarré la programmation regorgeaient de problèmes plus graves et rétrospectivement c’est pas si important : le débutant attentif saura raccrocher les wagons en lisant des documents un peu plus affûtés plus tard. Ça me fait aussi penser que les gros documents qui regroupent tout sont pas forcément une super idée. Une collection de tuto plus courts mais plus pointus (comme ce qu’on a ici pour Python) me semble une manière plus efficace à la fois de partager et d’absorber les connaissances, et que tout ce qui compte pour se lancer est plutôt un tuto qui apprend les cordes principales de "comment communiquer avec son ordi via un langage de programmation". On peut ensuite se plonger dans les méandres et détails sordides d’un langage donné avec des contenus dont c’est le but.

+1 -0

Les références à Pyhon 2 polluent considérablement le tuto.
Il faudrait annoncer dès le début qu’on va se situer dans un contexte Linux, de façon à na pas dérouter les utilisateurs de Mac OS ou de Windows..

Remarque de pinailleur :

https://frederic-lang.developpez.com/tutoriels/python/python-de-zero/?page=premiers-pas
II-4. Mode script
Par ailleurs, un script est considéré comme écrit en ASCII. Si ce n’est pas le cas (comme avec les éditeurs modernes qui ont tous pris l’option « utf‑8 » par défaut), l’interpréteur Python s’arrêtera en échec en arrivant sur une instruction contenant une chaîne accentuée.

Heu … sur mon PC, je fais bien pire que des lettres accentuées :
(Ce type de code est tout à fait déconseillé, mais de là à écrire que ça ne marche pas, il y a une marge. )

Python 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32   
>>>你好 = 'Bonjour !'  
>>>print(你好)  
Bonjour ! 
+1 -0

Ah, c’est carrément écrit ça ! Comme dit plus haut, c’était le cas en Python 2, plus du tout depuis Python 3, même si certains ont gardé l’habitude. C’est dommage d’écrire ça, même si fondamentalement, indiquer l’encodage en tête de fichier n’est pas très grave.

+1 -0

Bonjour

Merci de votre intérêt à mon tuto, je suis très flatté.

Je vais tenter de répondre à vos légitimes remarques…

1) concernant l’affectation a=42 vs a = 42 c’est mon habitude. Je viens du monde Unix et comme tel j’ai d’abord été shell avant d’être tout le reste. Et en shell l’espacement est interdit dans l’affectation. Et (malheureusement pour les puristes) j’ai gardé cette façon d’écrire dans les autres langages (C, Python, Powershell). Toutefois dans mon tuto je ne dis pas que ce style d’écriture est obligatoire (mais je ne dis pas non plus qu’il ne l’est pas). Bon je vais rajouter ce détail.

2) le coding: c’est un peu pareil: j’ai commencé Python en 2005 et à cette époque c’était du P2. Et quand je suis passé à P3 j’ai commencé par copier mes scripts pour les mettre à jour sans tester si cette obligation l’était toujours. En effet elle ne l’est plus mais là encore c’est une indication que j’aime bien. Et puis n’oublions pas le zen de Python: explicite vaut mieux qu’implicite.

3) le match… case effectivement il a été rajouté plus tard. Effectivement quand ce tuto a été commencé, il n’existait pas encore. J’ai donc tenté de reproduire à cette époque une notion connue mais non implémentée. Et pour la représenter, il fallait bien un support d’où le C dont les professionnels affûtés que vous êtes ont effectivement repéré que c’était de là que je venais. Mais ce tuto n’est pas figé et je vais essayer de renforcer ce paragraphe

4) la remarque de adril m’interpelle. En effet on n’apprécie pas forcément qu’on vous dise "tu as écrit des conneries" et bon donc je "m’empêtre" dans plein de trucs… J’ai essayé de balayer très large mais qui peut se vanter de tout connaitre? Encore aujourd’hui j’apprends des choses (je suis en train d’étudier les descripteurs, ce qui m’a alors orienté au préalable sur les fonctions getattr(), setattr() et delattr() dont je ne connaissais pas l’existence). En parallèle je suis tombé sur des détails à propos du MRO dont je n’avais pas idée ce qui m’a amené à remettre en cause l’utilisation systématique de super() en cas d’héritage multiple => fonctionnement de super et nécessitera ensuite une remise à jour de ce tuto. Mais pour en revenir aux dict, de mon point de vue, les iterkeys() et autres ont bel et bien disparu en P3. Ce n’est pas parce qu’on peut reproduire leur comportement au travers d’autres outils que ça change ce fait. Mais c’est bien de tomber sur des professionnels critiques, ça me remet de l’humilité dans le citron ;) Je serai heureux de reprendre certains détails (il dit que c’est un peu partout) à condition aussi d’accepter qu’on ne puisse pas non plus descendre au fond du fond (le diveintopython est fait pour ça).

5) les parallèles avec P2: c’est là encore un peu pareil. A l’époque où ce tuto a débuté, P2 était encore bien présent. Et évidemment plus le temps passe, moins c’est pertinent. Toutefois on peut encore tomber sur de vieux codes P2 et le débutant aura peut-être alors besoin de savoir ce qu’était xrange(), iterkeys(), viewkeys() etc. Il pourra peut-être se demander pourquoi il ne voit pas de "//" tout en ayant des divisions entières, etc etc etc

6) l’écosystème Python (pip, etc). Oui je ne l’ai pas mis, je suis humain donc limité. J’ai aussi un peu tendance à penser que cela est du ressort de l’admin et non du dev que d’installer ce qu’il faut. Mais d’un autre côté, avec la possibilité de créer des environnements personnels avec ses propres outils, le dev peut aussi jouer un rôle là dedans. Désolé, c’est un peu du "pile ou face"

Donc voilà, j’espère vous avoir un peu éclairé sur ce tuto que je suis heureux de pouvoir partager avec vous.

PS: désolé que vous considériez DVP comme de la concurrence. Perso je pense que plus le savoir est diffusé, mieux il peut se propager. Je serai heureux de collaborer avec vous comme je collabore avec eux.

Cordialement

+0 -0

Pour ma part je n’ai fait que survoler très brièvement, mais concernant les points que tu relèves :

  1. C’est loin d’être indispensable mais je pense quand même que dans un cours pour débutant·e·s il est préférable d’adopter la syntaxe et les idiomes habituels du langage, pour éviter de donner de mauvais habitudes. On ne code pas en Python comme on code en C ou en shell.

  2. Oui pourquoi pas, et c’est toujours bien de causer un peu des encodages de fichiers pour prévenir les problèmes.

  3. Je n’ai pas grand chose à dire là-dessus puisque j’ai déjà rencontré pas mal de fois la syntaxe que tu utilises avec un dictionnaire. Par contre je ne l’associe pas au switch-case (même si ça permet de combler un de ses aspects), si on voulait faire une analogie avec le C ce serait plus un tableau de pointeurs sur fonction, par l’aspect dynamique de la structure.

  4. N’ayant pas eu le temps de lire le cours pour le moment je ne peux pas t’en faire une liste complète, mais c’est vrai qu’il y a des choses qui font tiquer. Par exemple ici tu utilises des annotations qui ne sont pas correctes (a:(int,float)=5). Voilà par exemple ce qu’en pense mypy :

    % cat annotation.py
    a:(int,float)=5
    % mypy annotation.py
    annotation.py:1: error: Syntax error in type annotation  [syntax]
    annotation.py:1: note: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn)
    Found 1 error in 1 file (checked 1 source file)
    
  5. Fort heureusement Python a évolué depuis sa version 2, je trouve que c’est bien de rappeler comment cette dernière fonctionnait (avec par exemple des tableaux comparatifs) mais dans un chapitre dédié (pour les personnes qui rencontrerait justement un code en Python 2) plutôt que par des détails parsemés un peu partout. Là ça donne l’impression d’un cours, pourtant publié en 2022, qui aurait mal vécu la transition vers Python 3.

  6. Je suis d’accord qu’il ne faut pas nécessairement trop s’étaler dessus (et y a tellement de choses à en dire et de manière différentes de faire que ça mérite en cours complet), mais c’est bien de présenter comme installer quelques dépendances.

la remarque de adril m’interpelle. En effet on n’apprécie pas forcément qu’on vous dise "tu as écrit des conneries". J’ai essayé de balayer très large mais qui peut se vanter de tout connaitre? Encore aujourd’hui j’apprends des choses (je suis en train d’étudier les accesseurs et descripteurs, ce qui m’a alors orienté au préalable sur les fonctions getattr(), setattr() et delattr() dont je ne connaissais pas l’existence). En parallèle je suis tombé sur des détails à propos du MRO dont je n’avais pas idée. De mon point de vue, les iterkeys() et autres ont bel et bien disparu en P3. Ce n’est pas parce qu’on peut reproduire leur comportement au travers d’autres outils que ça change ce fait. Mais c’est bien de tomber sur des professionnels critiques, ça me remet de l’humilité dans le citron ;) Je serai heureux de reprendre certains détails (il dit que c’est un peu partout) à condition aussi d’accepter qu’on ne puisse pas non plus descendre au fond du fond (le diveintopython est fait pour ça).

Cette réponse et en particulier la dernière phrase me laisse penser que ma remarque n’était pas claire sur un point. Je ne suis pas en train d’argumenter qu’il faut "descendre au fond du fond", je suis en train de dire exactement l’inverse. C’est un tuto pour débutant, donc à ta place j’enlèverai complètement les considérations Python 2, et je m’abstiendrais d’aborder des nuances fines du genre iterable vs generator avant que le lecteur n’ait été introduit proprement à ces concepts. Rien qu’enlever tous les parallèles à Python 2 rendrait le propos considérablement plus clair et accessible, et enlèverait une partie des approximations présentes dans ton contenu.

les parallèles avec P2: c’est là encore un peu pareil. A l’époque où ce tuto a débuté, P2 était encore bien présent. Et évidemment plus le temps passe, moins c’est pertinent. Toutefois on peut encore tomber sur de vieux codes P2 et le débutant aura peut-être alors besoin de savoir ce qu’était xrange(), iterkeys(), viewkeys() etc. Il pourra peut-être se demander pourquoi il ne voit pas de "//" tout en ayant des divisions entières, etc etc etc

À mon avis, tout ce qu’un débutant à besoin de savoir, c’est que Python 2 existe, n’est plus supporté, et a des différences plus ou moins subtiles avec Python 3 qui le rendent incompatible. Il faut juste savoir ça pour pouvoir fuir ce qui concerne Python 2 lorsqu’on cherche quelque chose en Python 3 pour éviter de tomber dans un piège. Un débutant n’a pas besoin de savoir ce que sont xrange et compagnie, parce qu’un débutant peut vivre complètement dans le monde Python 3 en ignorant tout code Python 2 qui lui tombe sous les yeux. Le seul besoin de lire du code Python 2 aujourd’hui vient lorsqu’on doit maintenir/porter du code legacy, ce qui n’est pas une considération de débutant.

l’écosystème Python (pip, etc). Oui je ne l’ai pas mis, je suis humain donc limité. J’ai aussi un peu tendance à penser que cela est du ressort de l’admin et non du dev que d’installer ce qu’il faut. Mais d’un autre côté, avec la possibilité de créer des environnements personnels avec ses propres outils, le dev peut aussi jouer un rôle là dedans. Désolé, c’est un peu du "pile ou face"

Je réponds en particulier à cette phrase : "J’ai aussi un peu tendance à penser que cela est du ressort de l’admin et non du dev que d’installer ce qu’il faut". Je pense que tu te plantes de philosophie. Une des forces de Python est son côté couteau-suisse et le fait qu’il vienne (contrairement aux technologies comme C ou C++ que tu connais mieux) avec une façon standard et centralisée (avec pip et PyPI) de distribuer des packages, qui sont même précompilés (avec le format wheel). Pas besoin donc de comprendre les méandres de la build pour installer et utiliser une bibliothèque. Ça veut dire qu’un développeur Python n’a que très rarement besoin de réinventer la roue parce qu’il a tout un écosystème très riche de bibliothèques prêtes à être installées dans un venv. Ça me parait beaucoup plus fondamental et important de montrer ça au débutant que de s’attarder sur des parallèles avec une version morte du langage. Tu as, comme tu le dis toi même, des ressources limitées à investir dans le tuto, autant se concentrer sur ce qui important. La plupart des débutants Python vont rapidement avoir besoin d’installer des paquets qui ne sont pas présents dans la librairie standard pour pouvoir coder ce qu’il ont envie (comme un petit jeu par exemple). C’est un besoin réel, autant y répondre.

PS: désolé que vous considériez DVP comme de la concurrence. Perso je pense que plus le savoir est diffusé, mieux il peut se propager.

Soyons sérieux, on ne joue pas du tout dans la même cours que DVP, ne serait-ce que l’échelle du site ! Nous ne sommes pas en concurrence. Par ailleurs, si on était en désaccord avec la seconde phrase, on aurait sûrement une clause dans nos règles du forum et une modération qui privilégie fortement les liens internes.

+3 -0

Ok ok ok, effectivement les annotations j’ai fait un super loupé. Je suis allé fouiller le net. Je ne me souviens pas du tout comment j’en suis arrivé à me persuader (parce que si je l’écris c’est parce que c’est ce que je crois) qu’une annotation multiple (style "int" ou "float") s’écrivait (int, float). Peut-être par atavisme avec la syntaxe de isinstance() qui demande que les types soient mis dans un tuple si elle doit en checker plusieurs. C’est un gros point qu’il va me falloir reprendre.

Sinon la remarque sur la transition P3 c’est exactement ça. Au début c’était effectivement un cours P2. Et c’est quand je me suis mis à P3 que j’ai tenté de le convertir en cours P3. Avec donc certainement des maladresses. Oui peut-être que les considérations P2 devraient disparaitre maintenant.

Concernant le PS sur la "concurrence" c’était à propos de ce terme employé dans le tout premier post

Pour pip/pip3 ok, s’il faut en parler je peux m’y mettre.

+0 -0

Zeste de Savoir n’a absolument aucune volonté de concurrence :) Le seul objectif du site est la transmission de connaissances, et ses préoccupations sont la fiabilité et la qualité pédagogique. Le reste nous importe peu, et au contraire on sera là pour encourager toutes les autres initiatives gratuites (developpez.com, mais aussi wikilivres, les vulgarisateurs twitch, les blogs personnels…) et parfois également payantes, le but étant que chacun trouve ce qui lui convient.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte