Rédaction d'une collection de tutoriels Python

Qui ? Quoi ? Comment ?

a marqué ce sujet comme résolu.

Plop nohar,

Alors justement, on en a discuté avec entwanne et c'est en train de se mettre en place (j'ai créé le tutoriel hier sur ZdS), je t'ajoute à la conversation et au tutoriel.

Pour le reste, j'aimerais bien contribuer à faire avancer le tutoriel de martinqt ou le tien, mais je dois faire des choix ^^

Plop. Où en est le projet de tuto POO ?

Je suis intéressé pour l'écrire, et celui-ci fait partie du chemin critique donc il est plutôt prioritaire.

Quelqu'un a-t'il déjà créé le dépôt ?

nohar

J'ai reçu la semaine dernière un message de Smokiev qui se disait intéressé par la rédaction du cours, et qu'il commencerait prochainement l'ébauche d'un plan.

J'y apporte aussi mon soutien sans avoir énormément de temps à consacrer à la rédaction (donc plus un soutien sur le plan et les points à apporter/détailler, ainsi que la relecture).

Pas de dépôt existant à ma connaissance, mais ce serait un bon début. À voir avec Smokiev s'il a déjà prévu quelque chose.

De même, le tuto débutant de martinqt semble être arrivé à stagnation donc j'envisage de reprendre l'écriture de celui que j'avais commencé, car il aborde le sujet avec un angle original par rapport au reste de la littérature francophone, et que ZdS a vraiment besoin de ce type de contenu pour devenir une référence.

nohar

J'appuie fortement cette idée, l'approche que tu présentais dans ton cours me paraissait plus intéressante.

Edit : Ah, ben grillé de peu :)

Salut,

Comme l'article de l'année dernière à été apprécié, je vais relancer la rédaction d'un pour Python 3.6. actuellement la alpha 1 est sorti. La beta 1 sortira début septembre et ce sera le feature freeze pour une sortie en décembre. Donc on est large. Si certains veulent m'aider…

Pour info, actuellement la seule "grosse" nouveauté pour les utilisateurs est l'interpolation de chaine comme on le pressentait dans les perspectives du dernier article.

Petite surprise, su Python-dev la grosse discussion actuelle est de faire passer les dict en OrderedDict (tous les dico conserveraient l'ordre d'insertion). Ça peut paraître anodin mais vu que les dict sont partout en Python ça a des effets de bords tel que les **kwargs et __dict__ seraient aussi ordonné (on pourrait connaître l'ordre de passage des arguments et dans quel ordre les champs sont déclarés dans les classes). Cette modification est assez attendu de ceux qui utilisent Python comme pseudo-DSL. Ça peut aussi éviter des hooks pas propre dans les ORM par exemple.

Ha j'ai oublié un truc. Il est fort probable que l'utilisation des JIT compiler dans le monde Python se démocratisent. Il en existe déjà beaucoup (PyPy, Pyston, numba, Jython, IronPython, etc.) mais sont relativement peu utilisés. Entre autre parce que la majorité on un support partiel de l'API C. Une solution nous vient, une fois n'est pas coutume, de Microsoft ou deux de leurs devs ont, sur leur temps libre, développé Pyjion. La partie intéressante pour nous est leur objectif #1 qui est en passe d’être atteint.

L'idée est d'ajouter à l'API C de CPython des hook permettant d'installer un JIT. En très gros l'idée est de permettre d'enregistrer une fonction (en C) qui doit se charger de l'évaluation des frames. Donc permettre de remplacer uniquement la partie de CPython qui s'occupe de l'évaluation du bytecode.

Cette façon de faire a plusieurs avantages :

  • un simple import truc (voir en utilisant un argument de la ligne de commande) permettrait que tout le code exécuté le soit par le JIT "truc" plutôt que par CPython. C'est beaucoup moins lourd qu'un interpréteur a coté.
  • Les JIT peuvent se concentrer sur leur spécificité (executer le code) et n'ont pas besoin de devoir refaire un parseur.
  • Toutes les extensions C continuerais à fonctionner.

Guido est pas loin d'accepter la PEP. Actuellement ça discute sur des détails d'implémentations pour éviter que cet ajout ne pénalise les codes qui ne l'utilisent pas.

+2 -0

Que de bonnes nouvelles !

J'avais assez peu suivi cette nouvelle version et ne savaient pas où ils en étaient pour la version ordonnée de **kwargs (j'en étais resté au moment où ils se demandaient s'il ne fallait pas ajouter un opérateur *** pour en récupérer une version ordonnée, ou une autre variable __kworder__, PEP 468). La solution adoptée m'étonne pas mal : ne risque-t-elle pas de causer un énorme surcoût ?

Quant à l'interpolation, ça va donner une 3ème manière de procéder, et j'avais été déçu que le préfixe i ne soit pas lui aussi accepté (PEP 501).

Sinon, je suis potentiellement intéressé pour participer à la rédaction de l'article.


Autre chose tant que j'y suis, je continue l'écriture du tutoriel objet, qui n'a pas beaucoup avancé ces dernières semaines. Je travaille actuellement sur une réécriture de l'ensemble, afin de donner plus de liant.

En fait concernant les OrderedDict c'est pas encore sûrs. Le fait est qu'il n'y a pas que dans les kwargs que c'est demandé. Il y a aussi l'ordre de définition des membres de classes qui sont demandé pour éviter de devoir recourir aux métaclass et __prepare__. Pour le moment c'est pas sûrs. Guido semble intéréssé par la solution de faire de dict un OrderedDict car c'est déjà ce que fait PyPy et ça réglerai toutes ces demandes d'un coup sans devoir ajouter de la syntaxe ou de nouvelles méthodes spécial. Depuis Python 3.5 les OrderedDict sont codé en C et sont donc plus rapide. Si j'ai bien compris ce n'est pas directement cette classe qui serai ajouté mais une autre, appelé "compacted ordered dict" qui serait plus optimisé pour répondre au besoin de remplacement des dev (préserverai l'ordre mais serait plus efficace en supprimant quelques features non indispensable des OrderedDict).

Mais pour le moment c'est du projectif. Il n'y a rien de décidé ni de mergé (même si il y en a qui bossent dessus). Si j'en parle c'est que cette nuit Guido a sous entendu que ça pourrait être la solution si ça pouvait être prêt pour le feature freeze.

Pour le moment la seule chose confirmé est l'interpolation de chaines. La PEP 501 n'est pas vraiment refusé, ils préfèrent attendre de voir l'utilisation de cette première version avant d'ajouter ça.

La solution adoptée m'étonne pas mal : ne risque-t-elle pas de causer un énorme surcoût ?

entwanne

Je n'ai pas suivi les derniers développements du sujet, mais ce n'est pas forcement pénalisant, c'est exactement ce que fait pypy par exemple.

Si j'ai bien compris ce n'est pas directement cette classe qui serai ajouté mais une autre, appelé "compacted ordered dict" qui serait plus optimisé pour répondre au besoin de remplacement des dev (préserverai l'ordre mais serait plus efficace en supprimant quelques features non indispensable des OrderedDict).

Kje

Ça fait déjà partie des solutions alternatives envisagées pour la PEP 468. Si j'ai bien suivi l’idée originale de R. Hettinger, il y a plusieurs implémentation possibles, et la plus efficace ne préserve plus l'ordre une fois que l'on commence a faire des deletions sur le dict.

A l'origine, le but n'est pas du tout de preserver l'ordre, mais surtout de rendre les dict plus compacts et donc plus cache-friendly, mais il se trouve que cette facon de faire a comme effet de bord de maintenir l'ordre d'insertion des cles, du moins tant que l'on ne supprime rien. La encore, je ne sais pas ou ça en est actuellement.

+0 -0

Justement Guido à mit des doutes sur ce point. Il voudrait que l'ordre soit conservé en cas de suppression. Il y a une implémentation alternative qui a été proposé .

Mais en gros pour l'instant rien n'est décidé. J'en parle car c'est la discussion chaude du moment et c'est un changement non négligeable mais si ça se trouve il n'y aura pas ça dans la prochaine version.

Justement Guido à mit des doutes sur ce point. Il voudrait que l'ordre soit conservé en cas de suppression. Il y a une implémentation alternative qui a été proposé .

Kje

Oui, c'est clairement possible de le faire (c'est ce que faisait le proof-of-concept original, et il me semble que pypy le fait aussi), mais du coup les deletions font des « trous » dans la structure, et il est nécessaire de recompacter de temps en temps (et du coup c'est sans doute un poil moins efficace).

Du coup, tout le travail de E. Snow sur les OrderedDict en C de la 3.5 aura été vain ?

+0 -0

Du coup, tout le travail de E. Snow sur les OrderedDict en C de la 3.5 aura été vain ?

J'en sais rien c'est pas du tout clair en fait. Le compacted dict peut très bien être utilisé lors de l'évaluation de la définition de class et copié vers __dict__ qui serait un OrderedDict. Il y a déjà lors de l'évaluation des classes une structure particulière pour le scope qui est copié dans __dict__ en fin d'évaluation. On aura donc peut être un fonctionnement similaire. le coté compacted dict est peut être uniquement pour les procédure interne à CPython et l'OrderedDict serait alors le remplaçant du dict coté python. C'est un peu dur de savoir pour le moment.

+0 -0

De mon côté j'ai décidé de micro-tasker mes gros tutoriels, si vous voulez bien me pardonner cet anglicisme barbare. C'est-à-dire que je suis en train de bosser sur un mini-tuto niveau débutant sur le système d'exceptions de Python, de la syntaxe de base aux bonnes pratiques avec plein d'exemples concrets (qui m'a été inspiré par un récent post sur le forum).

Le but est de faire le tour complet de la question, tout en restant accessible à des lecteurs qui n'ont jamais fait de POO, mais en allant assez loin pour apprendre aussi des trucs aux développeurs plus chevronnés. Typiquement, j'en profite dans ce tuto pour expliquer ce qu'est une stack frame, ce que je n'ai jamais lu dans un tuto sur les exceptions alors que c'est pourtant vital de savoir comment Python produit ses tracebacks…

Je compte morceler tous mes gros projets de cette manière, parce que sans ça, ça n'avancera jamais. De cette façon je peux espérer sortir au moins un contenu pertinent tous les mois.

+5 -0

Coucou, (énième réveil du sujet)

Rien n'empêche de faire en parallèle un petit tuto sur l'install auquel vous faites référence dans les autres.

nohar

Ça me plaît bien l’idée d’un tutoriel sur l’installation de Miniconda et son utilisation. Comme ça, les autres tutoriels auront une bonne base vers laquelle renvoyer pour les installations. En plus, ça permet une certaine harmonie entre les tutoriels. Quelqu’un a déjà commencé son écriture ?

Karnaj

Avant, non. Maintenant, oui.

J'ai commencé un tuto sur (ana|mini|ø)conda. C'est clairement pas le truc le plus fun à écrire, je vais donc essayer de le boucler avant de perdre ma motivation. Je fais au plus simple : un type qui veut faire du python scientifique doit bien être capable de suivre des instructions d'installation basiques.

Une fois le service minimum fait, je redirigerai probablement vers la doc. Si quelqu'un veut parler des environnements virtuels et autre trucs plus subtils, qu'il me contacte. Je ne ferai guère plus qu'en toucher un mot.

+2 -0

Bon en attendant que je me lance dans la rédaction de l'article de Python 3.6, je me sert de ce sujet de mémo-technique. Deux PEP viennent d'être acceptés et seront normalement dans Python 3.6 :

  • PEP 520 : L'objectif est d'être capable de savoir dans quel ordre ont été définit les attributs d'une classe. De l'extérieur les classes gagnent un attribut __definition_order__ qui est un tuple fournissant l'ordre dans lequel les attribut ont été définit. En pratique, le scope de définition d'une classe est maintenant un OrderedDict qui permet de récupérer cette info. Par contre __dict__ reste lui un proxy vers un dict classique, rien ne change de particulier.
  • PEP 487 : Ce n'est pas encore indiqué mais Guido l'a accepté hier. Le but est de simplifier l'implémentation de certains patterns lié à la customisation des classes sans passer par les méta-classes. En gros l'idée est de simplifier les principaux cas d'utilisation des méta-classes, un intermédiaire.

Premier ajout, __init_subclass__ qui permet, en gros, à une class fille (lors de sa définition) de passer des paramètres à la classe mère pour paramétrer la construction :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
>>> class QuestBase:
...    # this is implicitly a @classmethod (see below for motivation)
...    def __init_subclass__(cls, swallow, **kwargs):
...        cls.swallow = swallow
...        super().__init_subclass__(**kwargs)

>>> class Quest(QuestBase, swallow="african"):
...    pass

>>> Quest.swallow
'african'

Deuxième ajout, les attributs d'une classe qui contiendrons l'attribut __set_name__ le verra appelé avec une référence à la classe et le nom de l'attribut à l'initialisation. Cet ajout permet aux descriptors de s'initialiser tout seul sans l'utilisation de metaclass : l'objet connait à la fois la class dans laquel il est définit et le nom de l'attribut auquel il est rattaché. Exemple de la PEP:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import weakref

class WeakAttribute:
    def __get__(self, instance, owner):
        return instance.__dict__[self.name]()

    def __set__(self, instance, value):
        instance.__dict__[self.name] = weakref.ref(value)

    # this is the new initializer:
    def __set_name__(self, owner, name):
        self.name = name


class TreeNode:
    parent = WeakAttribute()

    def __init__(self, parent):
        self.parent = parent
+6 -0

Je suis dubitatif sur le second ajout. Je ne suis pas convaincu que complexifier le langage pour simplifier des cas d'utilisation marginaux soit une bonne idée dans l'absolu. D'autant plus après les ajouts de Python 3.5.

J'ai l'impression qu'on commence à un peu trop négliger le obvious de "There should be one, and preferably only one, obvious way to do it". Ok, les métaclasses sont un peu compliquées à prendre en main, mais à quoi bon simplifier leur usage lorsqu'on n'en a pas besoin 99 % du temps ? D'autant qu'une fois qu'on en a pigé le principe, c'est comme les décorateurs : ça finit par devenir une seconde nature.

Bref, le temps nous dira si c'était une bonne idée ou non. Mais j'avoue que jusqu'à maintenant cette version 3.6 me déçoit. Il y avait un monticule d'autres choses plus importantes à ajouter dans le langage plutôt que ça. À commencer par l'exposition des subinterpreters au runtime.

+1 -0

J'ai l'impression qu'on commence à un peu trop négliger le obvious de "There should be one, and preferably one, obvious way to do it".

Je comprends. Après j'imagine que cette PEP487 a vocation a devenir la façon de référence pour faire ce genre de choses. Techniquement la PEP520 est tout aussi inutile : la fonction __prepare__ des méta-classes permettait déjà de s'en passer.

Le principal argument en faveur de ces changements qui ont poussé ces PEP est que les méta-classes imposent d'hériter de la même. Si tu hérite de deux classes, chacune provenant d'une lib pour supporter une fonctionnalité différentes, et que les deux sont basés sur des méta-classes, tu as conflit et ça génère des erreurs qui sont considérés comme peu clair.

L'idée ici est que si la majorité des cas d'utilisations des méta-classes peut être géré par quelques unes de ces fonctions spéciales, tu devrais pouvoir faire disparaître ces conflits.

À commencer par l'exposition des subinterpreters au runtime.

Au dernière nouvelle celui qui s'en occupe est très chargé en ce moment et depuis plusieurs mois et n'a pas le temps de s'en occuper.


Pour le reste il reste jusqu'à fin septembre pour connaitre la liste des features exactes implémentés. Actuellement seul l'interpolation de chaine est pret. Les deux PEP cités devraient les rejoindre rapidement (des patch sont dispo). La seul autre fonctionnalité sur laquelle on peut parier c'est l'API pour pouvoir brancher les JIT (ou autre "interpreteur" d'évaluation de frame, PEP 523) dans CPython. Sinon il y a pas vraiment de sujet chaud. Mais il y a beaucoup de projets actuellement pour accélérer Python, que ce soit en interne (FAT Python) ou externe (la palanqué d'interpréteur/compilateur qui se lancent de partout, au passage IronPython semble ressuscité).

Il est un peu tôt je pense pour conclure sur cette version. Lors de la 3.5, les async/await ont été introduit seulement 2-3 semaines avant le feature-freeze.

Je suis content pour le __set_name__, les solutions actuelles pour imiter ce comportement étant assez inélégantes. Maintenant, ce n'était peut-être pas la peine de sortir une méthode pour cela, un simple attribut spécial __name__ aurait suffi amha.

__init_subclass__, j'y vois peu d'intérêt et je trouve que ça complexifie pas mal la création de classes.

Quant à __definition_order__, je n'ai pas vraiment d'avis, ça ne me paraissait pas trop demander de créer une métaclasse avec une méthode __prepare__ quand on a un besoin aussi particulier.

Je suis content pour le __set_name__, les solutions actuelles pour imiter ce comportement étant assez inélégantes. Maintenant, ce n'était peut-être pas la peine de sortir une méthode pour cela, un simple attribut spécial __name__ aurait suffi amha.

entwanne

J'imagine que pour c'est des cas particulier, genre un même objet référencé avec deux attributs : la fonction est appelée deux fois

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