RMLL 2005
> Python: meilleures pratiques de
développement
Stefane Fermigier
<sf@nuxeo.com>

08/07/2005


Qui je suis

Développeur Python depuis 1995

Contributeur (très occasionnel) à Python
et Zope depuis 1998

Fondateur et PDG de Nuxeo depuis
2000

Société de 25 personnes basée à Paris

Spécialistes de la gestion de contenu
d'entreprises (ECM) et du travail collaboratif

Développeurs de CPS, plateforme libre
d'ECM

Clients: grands comptes français et
internationaux
2
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Python ­ langage de programmation agile

(Very) High level language

Expressivité

Lisibilité du code (« executable
pseudocode
»)

Structures de données de haut niveau
(listes, dictionnaires)

Optimiser le temps de développement
plutôt que le temps d'exécution

Typage dynamique

Duck typing (« if it quacks like a duck, then
it's a duck
»)

Bénéfices: flexibilité et réutilisation

Équilibre entre simplicité et puissance
3
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Python, pour quoi faire ?

Scripting système ou d'applications
complexes

Outils pour générer du des bindings vers C,
C++, Fortran, Java, .NET, ObjectiveC...

Exemples: SWIG, SIP, Boost.Python, CXX,
Pyrex, JPype...

Utilisations

Scripting de type « shell » (10-50 lignes)

Tests automatiques

Couplage lâche de composants
4
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Python, pour quoi faire ?

Prototypage rapide d'applications

Productivité entre 3x et 10x celle de
langages non-agiles (selon Bruce Eckel)

Effort = (SLOC)^1.5 (loi de Brooks)

SLOC(Python) = SLOC(C)/4 ou SLOC(Java)/2.5

Time to market, développement évolutif

Certaines parties peuvent être
ultérieurement réécrites dans un langage
non-agile

Applications complètes de grande
envergure

Ex: CPS, ERP5, Chandler...
5
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL



Import this !
6
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Objectifs

Optimiser 3 variables:

Qualité

Durée

Effort (= prix)

À propos du prix

Années 50: machines = $$$, informaticiens
= gratuits (IBM: « achetez un mainframe,
on vous offre 2 informaticiens »)

Années 2000: informaticiens = $$$,
machines = quasi-gratuites
7
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


No silver bullet

« Also, il was observed that switching
from machine code to a high-level
programming language did not
guarantee all the benefits that were
hoped for. In particular, programmers
still produced, as willingly as before,
large chunks of ununderstable code, the
only difference being that now they did

it in a more grandiose scale, and that
high-level bugs had replaced low-level
ones »

E.W. Dijkstra
8
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Critères de qualité

Critères externes

Critères internes
9
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Critères externes

Correction (« couverture du périmètre
fonctionnel »)

Performances

Fiabilité

Robustesse, intégrité, sécurité

Utilisabilité

Compatibilité, interopérabilité
10
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Critères internes

Adhérence à un ou des standards de
programmation

Élégance, simplicité

Compréhensibilité, extensibilité,
maintenabilité

« Always code as if the guy who ends up
maintaining your code will be a violent
psychopath who knows where you live.
»
John F. Woods

Testabilité, vérifiabilité

Réutilisabilité, mutualisation
11
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Quelques principes
12
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Lisibilité

« When writing a program, our
audience is not the computer, our
audience is human »

Stefan Holek

Un programme passe souvent 80% de
sa vie en phase de maintenance
13
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Développement incrémental / agile

« That which remains quiet, is easy to handle.

That which is not yet developed is easy to
manage.


That which is weak is easy to control.

That which is still small is easy to direct.

Deal with little troubles before they become
big.

Attend to little problems before they get out of
hand.


For the largest tree was once a sprout,

the tallest tower started with the first brick,

and the longest journey started with the first
step.
»

Lao Tseu, Tao Te Ching (500 a.j.c)
14
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Développement incrémental / agile

Les méthodologies agiles visent à livrer
rapidement les fonctionnalités les plus
importantes pour le client

Elles encouragent le dialogue avec le
client et l'ouverture au changement

2 piliers au niveau de la
programmation:

Développement test-driven

Refactoring
15
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Test-driven

Dans sa forme la plus pure

On écrit un test

Il ne passe pas

On écrit la fonctionnalité

Le teste passe

Formes dégénérées

On écrit les tests à peu près en même
temps que le code

On vérifie que la couverture des tests est
conforme aux objectifs de qualité avec des
outils appropriés
16
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Refactoring

Identification des « bad smells », par
ex:

Mauvais nommage

Duplication de code (DRY, OAOO)

Classe / méthodes trop longues, trop
complexes

Manque de clarté

Manque de cohésion

Couplage trop fort

...
17
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Refactoring

Modifications incrémentales en
s'appuyant sur les tests unitaires

Déplacement de code (d'une méthode à
l'autre, d'une classe à l'autre)

Renommage

Changements d'algorithmes

...
18
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Problèmes avec le refactoring

Difficile de changer une API une fois
qu'elle est utilisée par des logiciels tiers

D'où vieilles API qui doivent être
maintenues, bit rot, etc.
19
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Best practices Python
20
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Idiomes de programmation Python

Cf. par exemple le Python cookbook

Ex:

Good: for x in l: f(x)

Bad: for i in range(0, len(l)): f(l[i])

Ex:

Good: s = l.join('')

Bad: for x in l: s += x

Ex:

if __name__ == '__main__': ...
21
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


PEP8

Indentation = 4 caractères, pas de tabs

1 instruction par ligne

Pas plus de 80 caractères par ligne

Couper les expressions trop longues en
sous-expressions, éviter les
continuations de ligne

Variables = small_caps

Classe = MixedCase

Méthodes = mixedCase

(Pseudo)constantes = ALL_CAPS
22
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Conventions de codage + métaphores

Extension de PEP8 car celui-ci ne couvre
pas tout

Besoin de s'adapter en fonction du
contexte de chaque projet

Vocabulaire, vision, métaphores
communs au projet
23
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Nommage

« The Named is the Mother of all
Things »

Lao Tseu, Tao Te Ching

Impact des design patterns = possibilité
de nommer des choses qui restaient
jusqu'à présent non-dites
24
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Nommage

Utiliser l'anglais

Ne pas mélanger les mots issus du
domaine métier et les mots techniques
(list, dict, etc.)

Choisir des noms « pas trop courts, pas
trop longs »

Eviter les abbréviations (cnt, lst...)
25
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Nommage des classes

Le nom d'une classe doit clairement
désigner sa raison d'être

Si vous n'arrivez pas à trouver des bons
noms pour vos classes, vous devez
probablement revoir vos abstractions
26
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Nommage des méthodes

Première partie du nom est un verbe
qui désigne une action

addToCart(), trimWhitespace()...
27
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Exemples

Good: shopping_cart.add(products,
quantity=1)

Bad: cart.addToCart(prod_list, 1)

Good: to_pay = shopping_cart.total
(currency)

Bad: sum = cart_session.computeTotal
(crcy)
28
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Commentaires

En anglais

Le commentaire explique le pourquoi du
code, l'intention du programmeur

Ex: pourquoi tel algorithme plutôt que tel
autre, dans quel

Le comment doit être clair à la lecture
du code, sinon = bad smell ->
refactoring
29
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Docstrings

Les docstrings sont une forme de
commentaire qui décrit le contrat que
remplit une classe ou une méthode (ou
éventuellement un objet)

Peuvent raconter une histoire

Très utile pour documenter une API

Ne doit pas être un substitut à un mauvais
nommage des méthodes

Elles peuvent facilement être manipulée
par introspection

myFunction.__doc__

help(myFunction)

Pydoc, Happydoc
30
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Docstrings

Possibilité d'utiliser des conventions
pour spécifier précisément le type des
arguments

Ont été détournées par la passé (avant
l'introduction des décorateurs) pour
ajouter des fonctions au langages

Ex: assertions de sécurité dans le anciennes
versions de Python, programmation par
contrats

Mais maintenant on a les décorateurs. c'est
plus propre
31
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Connaitre les librairies Python

Librairie standard

Librairies non-standards

Choisir le ou les bons frameworks pour
le travail à faire

Ex: Zope, Twisted, PEAK...
32
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Erreurs à éviter

from my_module import *

try/except non qualifié

Fautes d'orthographe dans les API
33
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Marqueurs (TODO, FIXME...)

Permettent de repérer les passages à
corriger ou à améliorer

Ne pas abuser des FIXME, « don't live
with broken windows »
34
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Attributs vs. accesseurs

Python ne décourage pas l'accès direct
aux attributs

Ex: obj.attr += 1

Ce n'est pas une « violation de
l'encapsulation » comme le prétendent
les intégristes de Java

Possibilité de passer par des properties
ultérieurement (refactoring)

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x'
property.")
35
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Tests

Tests unitaires

Niveau packages ou modules isolés les uns
des autres

Tests d'intégration

Tests de l'application dans son ensemble

Attaque directe de l'API

Tests fonctionnels

Attaquent l'application de l'extérieur =
black box testing (via HTTP pour les
applications web ou outils de tests
spécifiques pour les GUI)
36
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Tests unitaires avec PyUnit

Portage sous Python de SUnit
(SmallTalk) et JUnit (Java) de Kent Beck
& al

Module standard (unittest) de la librairie
Python

Syntaxe un peu lourde, « unpythonic »
selon certains, projets de remplacement
(ex: py.test)
37
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


PyUnit - Principe

Cas de tests regroupés dans des classes
héritant de TestCase

Méthodes testXXX() appelées les unes
après les autres (pas d'ordre particulier)

Méthodes setUp() et tearDown()
appelées respectivement juste avant et
juste après chaque test

Cas de tests regroupés dans des
TestSuites

Tests dans sous-répertoire tests

Selon XP/TDD, SLOC(tests) = 3x SLOC
(code à tester)
38
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL



PyUnit ­ Exemple
39
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Tests fonctionnels

Peuvent aussi utiliser PyUnit

Nécessitent une couche d'accès à
l'application à tester (HTTP, CORBA...)

La lisibilité peut poser un problème

Outils spécifiques clef en main

Functional doctests de Zope3

Outils externes

Rational, PushToTest, Parasoft... ($$$)

Maxq, TestMaker...
40
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Doctests

Tests unitaires (ou pas) insérés dans les
docstrings

Racontent une histoire

Avantage: mélanger doc et tests,
pousser à l'extrême une des idées de
XP, on est « sûr » que les docs sont
synchro avec le code
41
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL



Doctests ­ Exemple
42
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Liens tests et SCM

Lancent les tests unitaires / fonctionnels
de façon régulière

Exemples

Mozilla tinderbox

Buildbot

Apache Gump
43
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Contrôle automatique de qualité

Ex:

Pychecker

PyLint

Savent vérifier certaines erreurs de
base

Fautes de frappes

import *

Eventuellement non-respect de conventions

Complexité cyclomatique

Pas mal de faux positifs en général

On devrait pouvoir faire mieux
(inférence de type par exemple)

Projet PyPy
44
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Livraison / déploiement
45
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Distutils

Outils de build et de packaging
multiplateformes standard de Python

Usage

python setup.py build

python setup.py install

python setup.p bdist_rpm

Métadonnées et instructions de build
exprimées sous forme procédurale et
non déclarative
46
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Python eggs

Invention récente de Philip Eby

Similaire aux .jar de Java

Fichiers ZIP qui contiennent le code et
les métadonnées

Système de distribution global (à la
CPAN, Ruby gems...) en cours
d'élaboration
47
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Optimisation

Si nécessaire...

Identifier les parties critiques à l'aide du
profiler Python

Les réécrire en C ou autre
(éventuellement via Pyrex)

Bonne pratique: maintenir en parallèle
la version Python pure (qui sert de
référence = executable pseudocode) et
la version C

Ex: ElementTree et cElementTree
48
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Méthodologie

Outils de suivi

Bug / feature requests tracker

Mesurer ce qui doit l'être

Couverture des tests unitaires et
fonctionnels (coverage.py)

Pair programming / inspections / revues
de code

Readability counts (once again)
49
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


IDEs

Eclipse + PyDev

Eric

Boa

Wing (propriétaire et très bien)
50
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python by Tim Peters
51
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

1. Beautiful is better than ugly

On code pour les humains, pas pour les CPU

« How do we convice people that in
programming, simplicity and clarity ­ in
short, what mathematicians call 'elegance' ­
are not a dispensable luxury, but a crucial
mater that decides between success and
failure
» E.W. Dijkstra

Beautiful = « pythonic », ugly =
« unpythonic »

Il n'y a pas de substitut à l'expérience et au
bon goût

Facteurs psychologiques : « fun »,
« flow »
52
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

2. Explicit is better that implicit

Limiter l'effort de mémoire du développeur

Attention: il est possible de changer plein
de choses profondes et magiques dans le
langage

Méthodes "magiques" (__getattr__,
__setattr__, ...)

Métaclasses

Outils très puissants, mais ne pas en abuser !
53
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

3. Complex is better than complicated

Certains problèmes sont intrinsèquement
complexes

Exemple: si on doit s'interfacer ou
implémenter des standards existants
54
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

4. Flat is better than nested

5. Sparse is better than dense

Lisibilité encore

Dictionnaires plutôt que tableaux
55
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

6. Readability counts

« Readable is better than unreadable »

See #1
56
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

7. Special cases aren't special enough
to break the rules

La cohérence comme critère de simplicité

8. Although practicality beats purity

La simplicité au service du pragmatisme
57
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

9. Errors should never pass silently

Traîter correctement les exceptions

10. Unless explicitly silenced

Pas d'excepts non qualifiés

Grosse erreur récurrente dans les projets
Zope
58
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

11. In the face of ambiguity, refuse the
temptation to guess

Simplifier la compréhension

Ex: arguments nommés

frob(1, 0, 3) vs frob(verbose=1, gui=0,
debug=3)

12. There should be one-- and
preferably only one --obvious way to do
it

Opposé de la philosophie Perl

13. Although that way may not be
obvious at first unless you're Dutch

Guido = BDFL
59
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

14. Now is better than never

Prototypage rapide, développement évolutif

15. Although never is often better than
*right* now

S'applique au langage (ou aux frameworks)
plus qu'aux applications

Résister à l'introduction de nouvelles
fonctionnalités tant qu'il n'y a pas de choix
absolument clair
60
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

16. If the implementation is hard to
explain, it's a bad idea

17. If the implementation is easy to
explain, it may be a good idea

La simplicité de l'implémentation n'est pas
le seul critère
61
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python

18. Namespaces are one honking great
idea -- let's do more of those!

Les dictionnaires comme couteau suisse du
développeur

Contredit un peu PZ #4
62
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Zen of Python by SF

Pythonic is better than unpythonic
63
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL


Références / Thanks to

Kent Beck, Extreme Programming
Explained and Test Driven Development

Martin Fowler, Refactoring

Stefan « rock star » Holek, Choosing
Good Names

Alex Martelli et al, The Python Cookbook

David Ascher, Dynamic Languages --
ready for the next challenges, by design

Frederic Brooks, The Mythical Man-
Month

Guido van Rossum, Tom Gilb, Steve
Pemberton, Tim Peters, Bruce Eckel...
64
Copyright 2005 Nuxeo SAS ­ Licensed under the GNU FDL