Sexy Python
(en français)


Olivier Cortès
karmak@im.apinc.org


http://oliviercortes.com/

Mars 2014

Enquête rapide


Avez-vous déjà ressenti du fun à programmer ?

de manière prolongée ?

Quelque chose qui ressemble à une
addiction à un langage de programmation ?


En fait, ça s'appelle le flow.

Ça a été défini par notre ami Mihaly Csikszentmihalyi dans ses travaux sur le Mindfullness-Based Stress Reduction.

C'est TRÈS intéressant pour travailler empreint de coolitude avec des étoiles pleins les yeux.

Mais c'est pas le sujet.

On va plutôt voir pourquoi on peut
très facilement se taper des flows…

avec Python


« Python, c'est la classe » — @kaleo

« naaan, Python c'est sexy » — @karmak23

« vogl, les nains ! » — @leprof

Mediatiquement parlant,
Python est un langage McCain :

c'est ceux qui en parlent le moins…

… qui l'utilisent le plus, pardi !

(bonne mère !)

Python nous offre, dans le désordre :

compréhensions générateurs descripteurs décorateurs méta-classes introspection syntaxe respirante opérateurs ternaires gestionnaires de contexte dépaquetage d'arguments stdlib de ouf échange en place


Et plein d'autres choses afriolantes.

Alors on va voir tout ça.

La syntaxe respirante

Sans les accolades et les points virgules
— inutiles, il faut bien le dire —
il y a tout de suite moins de bazar à l'écran.

C'est bon pour les doigts, les poignets,
et surtout les yeux.

La syntaxe est explicite, pourtant elle est très concise :
on écrit beaucoup moins, mais on apréhende plus.

Il y a un coup à prendre pour l'indentation,
mais c'est bien peu comparé au gain de lisilité.

Et c'est géré par l'éditeur.

les opérateurs ternaires

Comme en C/Perl/PHP, mais lisibles.


x = 3 if what_a_test() else 5
					


Chaînables à loisirs.
Sinon ça resterait lisible ;-)

l'échange en place

Pour éviter les variables temp et titi-toto.


a, b = b, a
					

Voilà pour les amuse-gueules.

l'introspection

En Python, TOUT est objet.
Mais surtout, TOUT est introspectable au runtime.


def mafunction():
	""" Mon docstring de ouf. """
	pass
					

>>> print mafunction.__doc__
Mon docstring de ouf.
					

>>> dir(mafunction)
['__call__',
 '__class__',
   … un paquet de trucs …
 '__subclasshook__']
					

>>> print mafunction.__class__
<type 'function'>
					

Le langage est transparent pour le développeur.
C'est didactique, dangereux mais surtout ludique :-D

les générateurs

Des pseudo-listes dont les éléments
sont créés au fûr et à mesure.

Une déclaration explicite réduite au string ficelle :
Il suffit d'un yield dans une fonction.


def fibon(n):
    a = b = 1
    for i in xrange(n):
        yield a
        a, b = b, a + b
        			


Imbricables à loisir en Python 3 (yield from …).

Idéaux pour les co-routines, le buffering
ou les traitements gourmands en mémoire.

les compréhensions

Des créateurs concis de listes, dictionnaires ou générateurs.


ma_liste = [ el for el in generate_elems() if el.is_good ]
             		

mini_index = { x.field, x for x in elements }
             		

file_iterator = (chunk for chunk in iter_chunks()
                 if comment.match(chunk) is None)
             		


As usual, imbricables à loisirs (paracétamol recommandé).
On aime vraiment la concision chez Python.

Sur un générateur, c'est carrément la folie dans le studio :
On manipule les données sans limite avec des one-liners anonymes. Plus, plus.

le [dé]paquetage d'arguments

Ou le groupage de prototypes.


def ma_fonction(arg1, *args, mon_arg2=None, **kwargs)
             		

args sera une liste d'arguments anonymes,
kwargs un dictionnaire d'arguments nommés.

L'ordre est important (stickez à l'exemple).

Ça marche aussi dans l'autre sens, lors des appels :


mes_args = {'prems': 23, 'deuss': 'toto'}
ma_fonction(**mes_args)
             		

Jouissif dans les moteurs de templates, mais pas seulement.

les décorateurs

L'en{pilage,capsulation} facile de fonctions/méthodes.

Permet de construire des fonctions paramétrables,
complètement dynamiques, avec une syntaxe… concise.


@throttle(calls_per_minute=120)
@json_api_call(api_name='ma_belle_methode')
def ma_belle_function(arg1, arg2):
	…
             		

Les décorateurs s'empilent comme Shrek :
le plus haut est exécuté en premier lors de l'appel.

« @ » est une simple facilité d'écriture. Équivalent à :


ma_belle_fonction = json_api_call(…)(ma_belle_fonction)
             		

les gestionnaires de contexte

Encapsulation et contrainte de certains traitements.
L'exemple typique c'est le verrou, ou le fichier.


with BigLock(on=…):
	do_things()

with open('/etc/passwd', 'rw') as f:
	crack_user_password(line[0], line[2] for line in f.readlines())
             		


Déclaration explicite réduite à une feuille de vigne :

Il suffit d'implémenter __enter__(…) et __exit__(…).

__exit__ sera exécuté même en cas d'exception,
puis la relaiera.
La vie est bien faite.

la bibliothèque standard de ouf

Un peu comme si la Nespresso avec réservoir de lait
était livrée en standard,
intégrant un circuit arduino avec sa doc et un Macbook Air rétina pour 1€ de plus. (avec prise ethernet)

Difficile de citer des modules en particulier, il y en a tellement…

Ils sont bien documentés, et à jour par rapport aux dernières améliorations du langage (context managers, iterators…)

Mes grands classiques : re, datetime et logging. Sans oublier subprocess et operator. En dehors de la bibliothèque standard, mention spéciale à gevent. Cf. module of the week

les descripteurs

Permettent de surclasser les getters et les setters.

Exemple : pyredescr dans 1flow, où de simples attributs sont en fait stockés dans Redis. À part la déclaration, l'utilisation est 100% transparente pour le développeur.

À manipuler avec précaution :
potential usine à gaz inside.

La version édulcorée pour démarrer en douceur :
les properties.

les meta-classes

Permettent de personnaliser à mort tous les mécanismes de gestion des classes (instanciation, attributs de classes…).
(donc tout Python en fait, puisque tout est objet)

C'est via les méta-classes qu'on implémente le Singleton et d'autres design patterns plus ou moins singuliers.

Chaud-bouillant :
comme Python permet le monkey-patching par nature, il y a moyen de se tirer une roquette incendiaire dans le pied.

(mais c'est puissant, alors faut savoir que c'est possible)

Autres choses intéressantes


Spéciale dédicate à Maelig :
from __future__ import braces
et Python devient Java ;-)

Et voila.

On code ?

Pardon. Des questions ?

Et puis on code :-D

Merci à tous !