Organiser des programmes plus importants avec des fonctions

PythonPythonIntermediate
Pratiquer maintenant

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

Introduction

Au fur et à mesure que vos programmes commencent à devenir plus importants, vous voudrez être organisé. Cette section présente brièvement les fonctions et les modules de bibliothèque. La gestion d'erreurs avec les exceptions est également abordée.

Fonctions personnalisées

Utilisez des fonctions pour le code que vous voulez réutiliser. Voici une définition de fonction :

def sumcount(n):
    '''
    Renvoie la somme des n premiers entiers
    '''
    total = 0
    while n > 0:
        total += n
        n -= 1
    return total

Pour appeler une fonction.

a = sumcount(100)

Une fonction est une série d'instructions qui effectuent une certaine tâche et renvoient un résultat. Le mot clé return est nécessaire pour spécifier explicitement la valeur de retour de la fonction.

Fonctions de bibliothèque

Python est livré avec une large bibliothèque standard. Les modules de bibliothèque sont accessibles en utilisant import. Par exemple :

import math
x = math.sqrt(10)

import urllib.request
u = urllib.request.urlopen('http://www.python.org/')
data = u.read()

Nous aborderons les bibliothèques et les modules en détail plus tard.

Erreurs et exceptions

Les fonctions signalent les erreurs sous forme d'exceptions. Une exception provoque l'arrêt d'une fonction et peut entraîner l'arrêt de votre programme entier si elle n'est pas gérée.

Essayez ceci dans votre interpréteur Python interactif (REPL).

>>> int('N/A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'N/A'
>>>

À des fins de débogage, le message décrit ce qui s'est passé, où l'erreur s'est produite et une trace rétrospective montrant les autres appels de fonction qui ont entraîné l'échec.

Capturer et gérer les exceptions

Les exceptions peuvent être capturées et gérées.

Pour les capturer, utilisez l'instruction try - except.

for line in file:
    fields = line.split(',')
    try:
        shares = int(fields[1])
    except ValueError:
        print("Couldn't parse", line)
  ...

Le nom ValueError doit correspondre au type d'erreur que vous essayez de capturer.

Il est souvent difficile de savoir exactement quels types d'erreurs peuvent survenir à l'avance, selon l'opération en cours. Pour le mieux ou pour le pire, la gestion d'exceptions est souvent ajoutée après qu'un programme est tombé en panne de manière inattendue (c'est-à-dire : "oh, on avait oublié de capturer cette erreur. On devrait la gérer!").

Lèvement d'exceptions

Pour lever une exception, utilisez l'instruction raise.

raise RuntimeError('What a kerfuffle')

Cela entraînera l'arrêt du programme avec une trace d'exception. Sauf si elle est capturée par un bloc try-except.

% python3 foo.py
Traceback (most recent call last):
  File "foo.py", line 21, in <module>
    raise RuntimeError("What a kerfuffle")
RuntimeError: What a kerfuffle

Exercice 1.29 : Définition d'une fonction

Essayez de définir une fonction simple :

>>> def greeting(name):
        'Issues a greeting'
        print('Hello', name)

>>> greeting('Guido')
Hello Guido
>>> greeting('Paula')
Hello Paula
>>>

Si la première instruction d'une fonction est une chaîne de caractères, elle sert de documentation. Essayez d'entrer une commande comme help(greeting) pour voir cette documentation affichée.

Exercice 1.30 : Convertir un script en fonction

Prenez le code que vous avez écrit pour le programme pcost.py dans l'exercice 1.27 et convertissez-le en une fonction portfolio_cost(filename). Cette fonction prend un nom de fichier en entrée, lit les données du portefeuille dans ce fichier et renvoie le coût total du portefeuille sous forme d'un nombre à virgule flottante.

Pour utiliser votre fonction, modifiez votre programme de sorte qu'il ressemble à ceci :

## pcost.py
def portfolio_cost(filename):
    """
    Calcule le coût total (nombre d'actions * prix) d'un fichier de portefeuille
    """
    total_cost = 0.0

    with open(filename, "rt") as f:
        rows = f.readlines()
        headers = rows[0].strip().split(",")
        for row in rows[1:]:
            row_data = row.strip().split(",")
            nshares = int(row_data[1])
            price = float(row_data[2])
            total_cost += nshares * price

    return total_cost


import sys

if len(sys.argv) == 2:
    filename = sys.argv[1]
else:
    filename = input("Entrez un nom de fichier :")

cost = portfolio_cost(filename)
print("Coût total :", cost)

Lorsque vous exécutez votre programme, vous devriez voir la même sortie que précédemment. Après avoir exécuté votre programme, vous pouvez également appeler votre fonction de manière interactive en tapant ceci :

$ python3 -i pcost.py

Cela vous permettra d'appeler votre fonction à partir du mode interactif.

>>> portfolio_cost('portfolio.csv')
44671.15
>>>

Être capable d'expérimenter avec votre code de manière interactive est utile pour le test et le débogage.

Exercice 1.31 : Gestion des erreurs

Que se passe-t-il si vous essayez d'utiliser votre fonction sur un fichier avec des champs manquants?

>>> portfolio_cost('missing.csv')
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "pcost.py", line 11, in portfolio_cost
    nshares    = int(fields[1])
ValueError: invalid literal for int() with base 10: ''
>>>

À ce stade, vous êtes confronté à un choix. Pour que le programme fonctionne, vous pouvez soit nettoyer le fichier d'entrée original en éliminant les lignes erronées, soit modifier votre code pour gérer les lignes erronées d'une certaine manière.

Modifiez le programme pcost.py pour attraper l'exception, afficher un message d'avertissement et continuer le traitement du reste du fichier.

✨ Vérifier la solution et pratiquer

Exercice 1.32 : Utilisation d'une fonction de bibliothèque

Python est livré avec une large bibliothèque standard de fonctions utiles. Une bibliothèque qui pourrait être utile ici est le module csv. Vous devriez l'utiliser chaque fois que vous devez travailler avec des fichiers de données au format CSV. Voici un exemple de son utilisation :

>>> import csv
>>> f = open('portfolio.csv')
>>> rows = csv.reader(f)
>>> headers = next(rows)
>>> headers
['name','shares', 'price']
>>> for row in rows:
        print(row)

['AA', '100', '32.20']
['IBM', '50', '91.10']
['CAT', '150', '83.44']
['MSFT', '200', '51.23']
['GE', '95', '40.37']
['MSFT', '50', '65.10']
['IBM', '100', '70.44']
>>> f.close()
>>>

Une des bonnes choses du module csv est qu'il gère une variété de détails de bas niveau tels que les guillemets et la division appropriée par des virgules. Dans la sortie ci-dessus, vous remarquerez qu'il a enlevé les guillemets doubles des noms dans la première colonne.

Modifiez votre programme pcost.py de sorte qu'il utilise le module csv pour le parsing et essayez d'exécuter les exemples précédents.

✨ Vérifier la solution et pratiquer

Exercice 1.33 : Lecture à partir de la ligne de commande

Dans le programme pcost.py, le nom du fichier d'entrée a été codé en dur dans le code :

## pcost.py

def portfolio_cost(filename):
  ...
    ## Votre code ici
  ...

cost = portfolio_cost('portfolio.csv')
print('Coût total :', cost)

Cela est bien pour l'apprentissage et les tests, mais dans un programme réel, vous ne feriez probablement pas cela.

Au lieu de cela, vous pourriez passer le nom du fichier en tant qu'argument à un script. Essayez de modifier la partie inférieure du programme comme suit :

## pcost_1.33.py

import csv


def portfolio_cost(filename):
    """
    Calcule le coût total (nombre d'actions * prix) d'un fichier de portefeuille
    """
    total_cost = 0.0

    with open(filename, "rt") as f:
        rows = csv.reader(f)
        headers = next(rows)  ## Passez à la ligne d'en-tête
        for row in rows:
            if len(row) < 3:
                print("Ignorer la ligne invalide :", row)
                continue
            try:
                nshares = int(row[1])
                price = float(row[2])
                total_cost += nshares * price
            except (IndexError, ValueError):
                print("Ignorer la ligne invalide :", row)

    return total_cost

import sys


if len(sys.argv) == 2:
    filename = sys.argv[1]
else:
    filename = 'portfolio.csv'

cost = portfolio_cost(filename)
print('Coût total :', cost)

sys.argv est une liste qui contient les arguments passés sur la ligne de commande (s'il y en a).

Pour exécuter votre programme, vous devrez exécuter Python à partir du terminal.

Par exemple, à partir de bash sur Unix :

$ python3 pcost.py portfolio.csv
Coût total : 44671.15
bash %

Sommaire

Félicitations ! Vous avez terminé le laboratoire sur les fonctions. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.