Introduction
Dans cette partie, nous examinons de plus près la pratique de la rédaction de scripts Python.
This tutorial is from open-source community. Access the source code
💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici
Dans cette partie, nous examinons de plus près la pratique de la rédaction de scripts Python.
Un script est un programme qui exécute une série d'instructions et s'arrête.
## program.py
instruction1
instruction2
instruction3
...
Jusqu'à présent, nous avons surtout écrit des scripts.
Si vous écrivez un script utile, ses fonctionnalités et ses capacités vont grandir. Vous voudrez peut-être l'appliquer à d'autres problèmes connexes. Au fil du temps, il pourrait devenir une application critique. Et si vous n'y prêtez pas attention, il pourrait se transformer en un véritable bordel. Alors, organisons-nous.
Les noms doivent toujours être définis avant d'être utilisés par la suite.
def carré(x):
return x*x
a = 42
b = a + 2 ## Exige que `a` soit définie
z = carré(b) ## Exige que `carré` et `b` soient définies
L'ordre est important. Vous mettez presque toujours les définitions de variables et de fonctions vers le haut.
Il est une bonne idée de regrouper tout le code lié à une seule tâche dans un seul endroit. Utilisez une fonction.
def lire_prix(nom_fichier):
prix = {}
with open(nom_fichier) as f:
f_csv = csv.reader(f)
for ligne in f_csv:
prix[ligne[0]] = float(ligne[1])
return prix
Une fonction simplifie également les opérations répétées.
anciens_prix = lire_prix('anciens_prix.csv')
nouveaux_prix = lire_prix('nouveaux_prix.csv')
Une fonction est une séquence nommée d'instructions.
def nom_de_la_fonction(arguments):
instruction
instruction
...
return résultat
N'importe quelle instruction Python peut être utilisée à l'intérieur.
def foo():
import math
print(math.sqrt(2))
help(math)
Il n'y a pas d'instruction spéciale en Python (ce qui en facilite la mémorisation).
Les fonctions peuvent être définies dans n'importe quel ordre.
def foo(x):
bar(x)
def bar(x):
instructions
## OU
def bar(x):
instructions
def foo(x):
bar(x)
Les fonctions doivent seulement être définies avant d'être réellement utilisées (ou appelées) pendant l'exécution du programme.
foo(3) ## foo doit déjà être définie
Du point de vue de la présentation, il est probablement plus courant de voir les fonctions définies de manière du bas vers le haut.
Les fonctions sont considérées comme des briques de construction. Les blocs les plus petits/les plus simples sont placés en premier.
## myprogram.py
def foo(x):
...
def bar(x):
...
foo(x) ## Défini ci-dessus
...
def spam(x):
...
bar(x) ## Défini ci-dessus
...
spam(42) ## Le code qui utilise les fonctions apparaît à la fin
Les fonctions ultérieures s'appuient sur les fonctions antérieures. Encore une fois, il s'agit seulement d'un point de style. Le seul élément important dans le programme ci-dessus est que l'appel à spam(42)
soit placé en dernier.
Idéalement, les fonctions devraient être une boîte noire. Elles ne devraient opérer que sur les entrées passées et éviter les variables globales et les effets de bord mystérieux. Vos principaux objectifs : Modularité et Prédictibilité.
Il est recommandé d'inclure une documentation sous forme d'une chaîne de documentation (doc-string). Les doc-strings sont des chaînes écrites immédiatement après le nom de la fonction. Elles alimentent help()
, les IDE et d'autres outils.
def read_prices(filename):
'''
Lire les prix à partir d'un fichier CSV contenant des données nom,prix
'''
prices = {}
with open(filename) as f:
f_csv = csv.reader(f)
for row in f_csv:
prices[row[0]] = float(row[1])
return prices
Une bonne pratique pour les doc-strings est d'écrire un court résumé d'une phrase de ce que fait la fonction. Si plus d'informations sont nécessaires, inclure un court exemple d'utilisation ainsi qu'une description plus détaillée des arguments.
Vous pouvez également ajouter des indications de type optionnelles aux définitions de fonctions.
def read_prices(filename: str) -> dict:
'''
Lire les prix à partir d'un fichier CSV contenant des données nom,prix
'''
prices = {}
with open(filename) as f:
f_csv = csv.reader(f)
for row in f_csv:
prices[row[0]] = float(row[1])
return prices
Les indications ne font rien sur le plan opérationnel. Elles sont purement informatives. Cependant, elles peuvent être utilisées par les IDE, les vérificateurs de code et d'autres outils pour faire plus.
Dans la section 2, vous avez écrit un programme appelé report.py
qui affichait un rapport montrant les performances d'un portefeuille d'actions. Ce programme était composé de quelques fonctions. Par exemple :
## report.py
import csv
def read_portfolio(filename):
'''
Lire un fichier de portefeuille d'actions dans une liste de dictionnaires avec les clés
name, shares et price.
'''
portfolio = []
with open(filename) as f:
rows = csv.reader(f)
headers = next(rows)
for row in rows:
record = dict(zip(headers, row))
stock = {
'name' : record['name'],
'shares' : int(record['shares']),
'price' : float(record['price'])
}
portfolio.append(stock)
return portfolio
...
Cependant, il y avait également des parties du programme qui ne faisaient que effectuer une série de calculs scriptés. Ce code apparaissait vers la fin du programme. Par exemple :
...
## Afficher le rapport
headers = ('Name', 'Shares', 'Price', 'Change')
print('%10s %10s %10s %10s' % headers)
print(('-' * 10 +'') * len(headers))
for row in report:
print('%10s %10d %10.2f %10.2f' % row)
...
Dans cet exercice, nous allons prendre ce programme et l'organiser un peu plus solidement autour de l'utilisation des fonctions.
Modifiez votre programme report.py
de sorte que toutes les principales opérations, y compris les calculs et la sortie, soient effectuées par une collection de fonctions. Plus précisément :
print_report(report)
qui imprime le rapport.Prenez la dernière partie de votre programme et empaquetez-la dans une fonction unique portfolio_report(portfolio_filename, prices_filename)
. Faites en sorte que la fonction fonctionne de telle manière que l'appel de fonction suivant crée le rapport comme auparavant :
portfolio_report('/home/labex/project/portfolio.csv', '/home/labex/project/prices.csv')
Dans cette version finale, votre programme ne sera rien de plus qu'une série de définitions de fonctions suivies d'un seul appel de fonction à portfolio_report()
à la toute fin (qui exécute toutes les étapes impliquées dans le programme).
En transformant votre programme en une seule fonction, il devient facile de l'exécuter avec différents entrées. Par exemple, essayez ces instructions de manière interactive après avoir exécuté votre programme :
>>> portfolio_report('/home/labex/project/portfolio2.csv', '/home/labex/project/prices.csv')
... regardez la sortie...
>>> files = ['/home/labex/project/portfolio.csv', '/home/labex/project/portfolio2.csv']
>>> for name in files:
print(f'{name:-^43s}')
portfolio_report(name, '/home/labex/project/prices.csv')
print()
... regardez la sortie...
>>>
Python facilite grandement l'écriture de code de script relativement non structuré où vous avez simplement un fichier contenant une séquence d'instructions. Dans l'ensemble, il est presque toujours préférable d'utiliser des fonctions chaque fois que possible. A un moment donné, ce script va grandir et vous souhaiterez avoir un peu plus d'organisation. De plus, un fait peu connu est que Python exécute un peu plus rapidement si vous utilisez des fonctions.
Félicitations ! Vous avez terminé le laboratoire de script. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.