PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Evolution de Python 2   Recently updated !

samedi 30 janvier 2016 à 21:31

La communauté Python est assez d’accord ces derniers temps. Maintenant que le plus gros de la débâcle Python2/3 est derrière nous (en attendant le contre coup des retardataires de 2020) et qu’on a un modèle d’IO async bien clean, les trucs qui fâchent sont assez clairement délimités:

Sur ces questions, du travail est activement en cours.

Pour le multi CPU, un modèle propre permettra d’utiliser plusieurs interpréteurs en parallèle en partageant des valeurs
sans avoir à les sérialiser.

Pour les perfs, ce sera un taf plus long, mais:

Bref, y a du potentiel.

Pour le packaging, les wheels vont enfin arriver sous Linux, ce qui fait qu’on pourra bientôt pip installer des binaires partout. nuikta, le compilateur Python, supporte maintenant await/async.

On est sur la bonne route.

L’année 2016 va être trop cool, et dans mon enthousiasme, j’aimerais écrire à propos de choses que j’aimerais vraiment voir arriver dans Python.

try/except error inline

Beaucoup de codes en Python ressemblent à ça :

try:
    val = faire un truc
except MonErrorALaNoix:
    val = "valeur par default"

Par exemple :

try:
    val = stuff[index]
except (IndexError, TypeError):
    val = None

Ce sont des opérations si courantes qu’on a plein de raccourcis comme dict.get ou next(i, None). En effet, en Python try/except n’est pas juste un mécanisme de gestion d’erreur, c’est un mécanisme de contrôle de flux à part entière.

Car franchement, ça fait chier de se taper 4 lignes pour écrire ça. En effet, on a bien les expressions ternaires pour les if/else:

val = truc if bidule else machine

Et bien il exist un PEP (rejeté) qui propose ça:

val = faire un truc except MonErrorALaNoix: "valeur par default"

J’adore. C’est pratique, générique, propre.

Bien entendu ça peut être abusé, comme les expressions ternaires, pour faire de la merde illisible. Mais j’ai rarement vu le cas pour les précédentes, donc ça devrait aller.

slices sur les générateurs

Les générateurs, c’est formidable. C’est iterable. On peut les utiliser partout où on utilise les listes.

Sauf si on doit les limiter en taille.

Alors là, c’est relou.

Par exemple, récupérer les carrés des nombres pairs entre 0 et 100, puis limiter le tout a 10 éléments après les 5e:

from itertools import islice
g = (x * x for x in range(100) if x % 2 == 0)
g = islice(g, 5, 15)

Ca serait tellement plus simple de pouvoir faire:

g = (x * x for x in range(100) if x % 2 == 0)[5:10]

callable dans les slices

Si vous voulez tous les carrés des nombres au-dessus de 5, vous pouvez faire:

(x * x for x in numbres if x > 5)

Mais si vous voulez tous les nombres à partir du moment où vous rencontrez un nombre au-dessus de 5 ?

from itertools import dropwhile
numbers = dropwhile(lambda x: x > 5, numbers)
(x * x for x in numbres)

Alors certes, je ne suis pas pour transformer Python en Haskel et balancer des formules magiques comme:

(x * x for x in numbers[a -> a > 5])

Mais juste m’éviter l’import et pouvoir faire ça:

def start(x):
    return x > 5
(x * x for x in numbers[start:])

Ca serait cool.

with var dans les expressions génératrices

Je suis hésitant sur cette feature car c’est très tentant de faire de one liners trop longs avec, mais:

(x.split()[1] for x in truc if x.split()[1] == 1)

C’est con de faire 2 fois split quand même.

(y for x in truc 
   with x.split()[1] as y 
   if y == 1)

Bon, ça peut rapidement devenir illisible, donc à méditer.

async optionnel

Je cherche toujours à comprendre pourquoi async est nécessaire.

Avec les générateurs, la présence de yield fait détecter automatiquement la fonction comme fonction génératrice.

Avec await, ça devrait être pareil:

def stuff():
    await bidule # bim, c’est une coroutine !

Pas besoin de async. Si on veut faire une coroutine sans un seul await, il y a toujours @asyncio.coroutine.

async reste très utile pour async for et async with, mais perso j’aurais préféré avoir un await with et un await for et pas de async.

Après, le prenez pas mal hein. J’adore async/await. Vive asyncio ! Mais la syntaxe pourrait être plus naturelle, plus proche du comportement des générateurs, d’autant que ça se base dessus.

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?Evolution-de-Python-2-Recently-updated #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}