# Formatage des chaînes de caractères en Python

À l'intersection entre bonnes pratiques et optimisation comment afficher des chaînes de caractère en Python ? Privillégier la lisibilité ou l'optimisation ? Les deux mon capitaine !

Il existe deux méthodes assez classiques en Python pour formater des chaînes de caractère, à partir de signes plus (+) ou de %s. Considérons les chaînes de caractères suivantes :

    title = "optimisation" * 1000
    cat = "python" * 1000
    main_title = "biologeek" * 1000

Si l'on utilise des signes plus (+) :

    def foo1():
        page = ""
        for x in range(500):
            page += "<title>" + title + " - " + cat + " - " + main_title + "</title>"
        return page

Cette fonction s'exécute en 5,91 secondes, si l'on utilise des %s :

    def foo2():
        page = ""
        for x in range(500):
            page += "<title>%s - %s - %s</title>" % (title, cat, main_title)
        return page

Elle s'exécute dans le même temps. À choisir, beaucoup préfèrent la seconde (notamment en raison du lourd héritage d'autre langages préhistoriques...) mais heureusement il existe en python un moyen de faire encore plus lisible : utiliser des dictionnaires.

    def foo3():
        dic = {
            "title" : title,
            "cat" : cat,
            "main_title" : main_title
        }
        page = ""
        for x in range(500):
            page += "<title>%(title)s - %(cat)s - %(main_title)s</title>" % dic
        return page

Le temps d'exécution est ici aussi identique et si vous ne voulez pas créer de dictionnaire supplémentaire, il est possible de mettre directement le dictionnaire en argument :

    page += "<title>%(title)s - %(cat)s - %(main_title)s</title>" %\
    {"title":title, "cat":cat, "main_title":main_title}

Enfin il existe une dernière méthode utilisant les fonctions intégrées (pour en savoir plus, je vous renvoie sur l'excellent Dive into Python).

    def foo4():
        title = "optimisation" * 1000
        cat = "python" * 1000
        main_title = "biologeek" * 1000
        page = ""
        for x in range(500):
            page += "<title>%(title)s - %(cat)s - %(main_title)s</title>" % locals()
        return page

Mais elle met 6,07 secondes à s'exécuter et ce temps augmente avec le nombre de variables locales donc c'est moins performant... mais tellement pratique :-).

Conclusion, si vous voulez concilier les deux, à savoir optimisation et lisibilité, je vous conseille d'utiliser des dictionnaires pour formater vos chaînes de caractères et si vous n'avez pas nécessairement besoin d'aller vite locals() se révèle être très pratique (encore une fois faites des tests !).

Je vous rappelle qu'un billet récapitule l'ensemble des bonnes pratiques et optimisations en Python.

### Articles peut-être en rapport

- Bonnes pratiques et astuces Python
- Benchmarks map, filter vs. list-comprehensions
- Python : lisibilité vs simplicité

### Commentaires

szdavid le 22/01/2006 :

Intéressant...
Bon, là, j'utilise les %s ; la notion de l'utilisation des dictionnaires semble intéressante...
C'est incompatble avec mes développements actuels mais je vais regarder ça de plus près

Olivier le 23/01/2006 :

Elle est énorme la méthode avec dico !
J'achète ;)
Je ne trouve pas contre pas la première méthode si illisible que ça, franchement la seconde est bien plus difficile à lire lorsqu'on commence à avoir un nombre conséquent de variables.

David, biologeek le 23/01/2006 :

Oui, en fait ça dépend aussi beaucoup des habitudes de programmation et des langages connus.
Je corrige mon billet en conséquence.

littletux le 04/02/2006 :

ATTENTION : JE SUBIS avec un S
ÉNORMÉMENT DE SPAM ACTUELLEMENT ET J'AI DONC CONFIGURÉ DOTCLEAR POUR MODÉRER LES COMMENTAIRES A POSTERIORI
A PRIORI ? avant diffusion d'après ce que j'ai compris.
Mes 2 eurocents.
PS:
Très bonne idée ce petit texte informatif, je le note !

David, biologeek le 04/02/2006 :

En effet, oups bon de toute façon ça va changer incessamment sous peu :)