ProPython
6 astuces pour écrire du code "Pythonic"
11 Jul, 2021

6 astuces pour écrire du code "Pythonic"

Python est un langage considéré comme simple à apprendre et à prendre en main. En revanche, un code mal écrit peut vite devenir un enfer. C'est pourquoi il est important d'apprendre à faire du code clair et bien écrit : du code "Pythonic".

Cet article est la suite de 8 astuces pour écrire du code "Pythonic", pour plus d'astuces je vous invite donc à aller le voir !

F-Strings

On va commencer par une astuce dont vous ne pourrez plus vous passer après en avoir la connaissance. En effet, elle est à la fois "Pythonic", mais aussi très pratique. Il s'agit des f-strings, qui sont en fait des chaînes de caractères formatées. Elles vous permettent de mélanger du texte, des variables, des fonctions... tout ce que vous voulez, dans des chaînes de caractères. Voyons un exemple, qui vous permettra en même temps de comprendre la syntaxe :

>>> age = 18
>>> f"J'ai {age} ans"
"J'ai 18 ans"

On place un "f" avant d'ouvrir les guillemets de notre chaîne de caractères pour dire qu'on souhaite que ce soit une f-string, on écrit notre texte entre les guillements, et si on veut afficher une variable, on ouvre des accolades ("{}") et on met notre variable à l'intérieur. Cela évite de devoir concaténer des chaînes de caractères, et rend notre code plus clair. En effet, sans f-string, on aurait du écrire :

>>> "J'ai " + str(age) + " ans"
"J'ai 18 ans"

Ou encore :

>>> " ".join(["J'ai", str(age), "ans"])
"J'ai 18 ans"

Bref, vous l'aurez compris, la meilleure façon de mélanger du texte et des variables est d'utiliser des f-string.

On peut aussi mélanger ça avec des fonctions (ce qui est logique finalement puisque les fonctions renvoient des valeurs, qui sont donc considérées comme des variables) :

>>> f"J'ai {age*2} ans"
"J'ai 36 ans"

Opérateur Ternaire

Un opérateur ternaire évalue si une condition est vraie ou fausse, et effectue une opération si elle est vraie, et une autre si elle est fausse. Cela vous fait peut-être penser à une certaine structure conditionnelle : le if... else.... L'opérateur ternaire permet donc simplement de combiner à la fois un if et un else en une ligne. Voici la syntaxe :

valeur_si_vrai if condition else valeur_si_faux

Voyons ceci avec deux exemples :

>>> animal = 'araignee'
>>> nb_pattes = 8 if animal == 'araignee' else 4
>>> nb_pattes
8

>>> age = 12
>>> majeur = True if age >= 18 else False
>>> majeur
False

Vous commencez sûrement à comprendre la logique.

Attention cependant, le second exemple est là pour vous montrer quand il ne faut pas utiliser l'opéraeur ternaire. On ne l'utilise pas pour renvoyer True ou False parce que généralement on peut obtenir le même résultat encore plus simplement. Par exemple, on peut obtenir le résultat du deuxième exemple de cette façon :

>>> age = 12
>>> majeur = age >= 18
>>> majeur
False

Petit rappel au passage, puisqu'on parle d'astuces pour écrire du code "Pythonic" : le code suivant est très mauvais :

>>> def est_majeur(age):
...     if age >= 18:
...             return True
...     else:
...             return False
...
>>> est_majeur(12)
False
>>> est_majeur(18)
True

Mais celui ci est bon :

>>> def est_majeur(age):
...     return age >= 18
...
>>> est_majeur(12)
False
>>> est_majeur(18)
True
>>>

Il faut profiter du fait de pouvoir utiliser les conditions de cette façon en Python, cela permet d'avoir un code très clair et très léger.

Formattage Du Code

On parle tellement souvent du code en lui-même qu'on en oublie l'importance du formattage et de sa structure. En effet, vous avez beau écrire un code le plus clair et efficace possible, si tout est écrit sur une ligne (ce qui est impossible en Python et très caricatural) ce sera illisible. Il faut donc bien respecter certaines règles et conventions afin d'avoir un code agréable à lire et compréhensible. Ces conventions sont présentées sous le nom de PEP8. Bien évidemment, il est inutile de connaître toutes les règles et conventions, mais il faut au moins savoir dans les grandes lignes de quoi il s'agit. Vous connaissez déjà de nombreuses règles, par exemple en Python, on écrit les noms de variables et de fonctions en snake case, c'est à dire tout en minuscules, et les espaces sont remplacés par des tirets du 8.

Ce dont je vais parler maintenant est la longueur des lignes de votre code. PEP8 suggère de ne pas faire de lignes de plus de 79 caractères. Mais comment faire si vous avez par exemple un grand texte dans votre code, qui fait plus de 79 caractères ? Il suffit simplement de couper votre texte en plusieurs lignes. Python est très flexible à ce niveau, et vous permet de couper simplement vos lignes. Par exemple, pour un long texte :

lorem_ipsum = "Lorem ipsum dolor sit amet,\
 consectetur adipiscing elit.\
 Integer elementum..."

print(lorem_ipsum)
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.Integer elementum...'

Pour séparer un texte, et même toute instruction, sur plusieurs lignes, on utilise simplement un backslash au bout de la ligne, et on continue sur la ligne suivante.

Dans certains cas, on n'a même pas besoin d'un backslash. Par exemple, pour une liste :

colors = [
    'red',
    'green',
    'blue'
]

Manipuler Des Listes

Il existe de nombreuses façons de manipuler des listes en Python, beaucoup trop même. Il faut savoir quand utiliser quelle façon.

Enumerate

J'en ai déjà parlé, mais petit rappel pour ceux qui ne connaissent pas. enumerate vous permet de récupérer à la fois les index et les valeurs lorsque vous parcourez une liste. Voici un exemple :

>>> numbers = [3, 7, 2, 6]
>>> for index, number in enumerate(numbers):
...     print(index, number)
...
0 3
1 7
2 2
3 6

Cette fonction est très pratique en Python et vous devez absolument la connaître, elle permet d'écrire du code plus clair et compréhensible.

Manipulations complexes de listes

Pour des manipulations complexes, on utilisera la méthode classique. C'est à dire avec des boucles. Par exemple, imaginons que vous avez une liste et que vous souhaitez appliquer de nombreuses opérations sur chaque élément. Le mieux est de faire une boucle for afin de récupérer chaque élément à la suite, et d'appliquer vos opérations.

>>> for index, number in enumerate(numbers):
...     number += 3
...     number /= 5
...     number = number ** 2
...     numbers[index] = number
...
>>> numbers
[1.44, 4.0, 1.0, 0.45158399999999993]

Manipulations simples

Pour des manipulations plus simples, on préférera utiliser les compréhensions de liste. Elles vous permettent d'éviter d'écrire des boucles à tout va, et de les remplacer par des instructions en une ligne. Cependant, il est préférable de les utiliser uniquement pour des opérations simples puisque sinon la lecture du code peut être difficile.

Elles sont très utiles pour filtrer une liste par exemple :

>>> numbers = [3, 7, 2, 6]
>>> [number for number in numbers if number <= 3]
[3, 2]

En une ligne, on filtre une liste pour ne garder que les nombres inférieurs à 3, alors qu'il nous aurait fallu plusieurs lignes avec une boucle :

>>> for index, number in enumerate(numbers):
...     if number > 3:
...             del(numbers[index])
...
>>> numbers
[3, 2]

Arguments Mutables Par Défaut

Imaginons que vous souhaitiez utiliser une liste par défaut en argument d'une fonction, pour je ne sais quelle raison.

>>> def foo(numbers=[]):
...     numbers.append(2)
...     return numbers
...

Il faut être très méfiant, car l'argument par défaut numbers va créer une variable, qui ne sera créée qu'une fois, et non pas à chaque appel de la fonction comme pour les autres types d'arguments par défaut.

Vous ne comprenez pas ? Regardez cet exemple :

>>> foo()
[2]
>>> foo()
[2, 2]
>>> foo()
[2, 2, 2]

Le comportement normalement attendu est :

>>> foo()
[2]
>>> foo()
[2]
>>> foo()
[2]

Mais par je ne sais quelle magie noire, on n'obtient pas ça. En fait si, je sais. C'est ce que je vous ai dit plus haut, la variable numbers n'est créée qu'une fois, donc elle est réutilisée et modifiée à chaque appel de la fonction. Même si entre temps vous décidez de passer un paramètre plutôt que de laisser celui par défaut.

>>> foo([3])
[3, 2]
>>> foo()
[2, 2, 2, 2]

Ce n'est pas un bug, mais c'est bien une fonctionnalité du Python. Et ce problème est facile à régler, en utilisant None :

>>> def foo(numbers=None):
...     numbers = numbers or []
...     numbers.append(2)
...     return numbers
...
>>> foo()
[2]
>>> foo()
[2]
>>> foo([3])
[3, 2]

D'ailleurs, cela vous permet de voir une utilisation du mot-clé or en même temps. Il vous permet d'assigner plusieurs valeurs éventuelles à une variable : en effet, il assigne la valeur de la première valeur renvoyant True parmi les valeurs possibles. Voici un exemple, qui se suffit à lui même pour comprendre :

>>> 3 or 2
3
>>> None or 2
2
>>> [] or 2
2
>>> ['o'] or 2
['o']
>>> [] or {} or 3
3

Développer Une Librairie

La dernière astuce concerne les développeurs un peu plus avancés, qui aimeraient développer une librairie ou un framework, voir simplement un programme un peu plus complexe. Il faut dans ce cas en savoir un peu plus sur les structures et architectures de programmes, sinon vous n'allez pas vous en sortir.

J'ai par exemple créé plusieurs bots de trading, qui sont en fait le même mais avec des améliorations à chaque fois, et ce n'est qu'au bout d'un an que j'ai réussi à avoir un bon programme, bien clair et bien structuré. En fouillant dans mes anciens programmes je me rends compte à quel point c'est bordélique.

La première chose qui peut être intéressante à connaître est le concept de Design Patterns. Ce sont des solutions répondant à certains problèmes, et permettant de structurer votre code correctement, et donc d'écrire du code performant. Je ferai un article sur ce sujet, en attendant voici un très bon site pour en apprendre plus sur les Design Patterns : https://refactoring.guru/design-patterns/python. N'hésitez pas à y jeter un coup d'oeil si ça vous intéresse !

Le Mot De La Fin

C'est tout pour cet article ! Finalement, nous avons vu un peu plus de 6 astuces, puisqu'il y a quelques astuces supplémentairs glissées dans certaines parties. J'espère que vous aurez trouvé ça intéressant ! Sachez qu'il est essentiel d'écrire du code "Pythonic", et que je pense avoir fait quasiment le tour des astuces simples que je peux vous partager, le reste vous l'apprendrez surtout avec la pratique, et en cherchant à faire des programmes de plus en plus structurés et compréhensibles.

Si l'article vous a plus, que vous souhaitez laisser un retour, ou que vous avez des questions, n'hésitez-pas à laisser un commentaire ou à me contacter, je me ferai un plaisir de vous répondre !

On se retrouve prochainement pour d'autres astuces, si j'en découvre des nouvelles !

Laisser un commentaire

Premium - 15€/mois

L'accès à des articles inédits, à une multitude de ressources, à de nouveaux projets, mais également à des vidéos explicatives, découvrez ici pourquoi passer premium.

Articles liés

Catégories

Ressources

Retrouvez une collection de ressources (des scripts, des fiches résumé, des images...) liées aux articles du blog ou au Python.
Voir

Contact

contact@propython.fr
Se connecter pour envoyer un message directement depuis le site.

Navigation

AccueilSe connecterCréer un compteRessourcesPremium

Catégories

Pages légales

Politique de confidentialitéMentions légalesConditions générales de vente