Procédures et passage de paramètres



Nous avons déjà présenté des exemples très simples de procédures (sans paramètres).

Rappelons que les procédures représentent une catégorie de sous-programmes. Elles se distinguent des fonctions, une autre catégorie de sous-programme que nous aborderons ultérieurement.

L'objectif de cette partie du cours est de présenter les procédures de manière générale. Nous allons donc aborder ici le cas des procédures avec paramètres que nous introduirons par un exemple.



Exemple de procédures avec paramètres

Pour montrer l'intérêt des paramètres dans un sous-programme, nous allons utiliser deux versions d'un même projet (sans intérêt autre que pédagogique !) qui permet d'afficher l'adresse mail d'une personne de nom et prénom donné.

Voici les différents choix proposés par la boucle de saisie des données:

Mail-Choix.jpg, 8,5kB

Et voici, un exemple d'exécution lorsque l'utilisateur choisit Mail SFR:

Mail-Choix-SFR.jpg, 9,4kB

La première version du projet utilise uniquement des procédures sans paramètres. Elle se trouve dans le fichier Mail-Version1.py.

La deuxième version utilise une procédure paramètrée et se trouve dans le fichier Mail-Version2.py.

Première version du projet

La première version contient deux procédures nommées AdresseMail_SFR et AdresseMail_Free. Elles sont appelées dans la boucle de saisie des données:

 ....
 choix = 0

while (choix!=3) :
    print("Mail SFR : tapez 1")
    print("Mail Free : tapez 2")
    print("Arreter : tapez 3")

    choix = int(input("Votre choix : "))

    if choix == 1 :
        AdresseMail_SFR ()
    elif choix == 2 :
        AdresseMail_Free ()


 

Voici le code de la première procédure :

                                   
def AdresseMail_SFR() :
    prenom = input("Prenom : ")
    nom = input("Nom : ")
    print("Adresse mail : " + prenom+"."+nom+"@sfr.fr")

et voici celle de la seconde:

def AdresseMail_Free() :
    prenom = input("Prenom : ")
    nom = input("Nom : ")
    print("Adresse mail : " + prenom+"."+nom+"@free.fr")

On constate que ces deux procédures se ressemblent énormément. Mise à part le nom de la procédure, la seule chose qui change est le nom de la procédure et le nom de l'opérateur (en blanc dans le code ci-dessus) dans l'affichage de l'adresse mail.

En gros, on écrit deux fois le même code pour faire la même chose.

Deuxième version du projet

En utilisant une procédure paramètrée, on peut éviter cette répétition inutile de code. C'est ce que nous avons fait dans la deuxième version du projet.

Voici cette procédure:

def AfficherLeMailChez  (operateur) :
    prenom = input("Prenom : ")
    nom = input("Nom : ")
    print("Adresse mail : "+prenom+"."+nom+"@"+operateur+".fr")

Elle permet d'afficher le mail chez n'importe quel opérateur (représenté par le paramètre operateur). Nous avons en quelque sorte généralisé les deux procédures de la première version: pour obtenir l'adresse email, il suffit de concaténer le prénom, la chaine ".", le nom, la chaine "@", l'opérateur et la chaine ".fr".

Le code de la boucle de saisie des données se résume alors à l'appel de cette procédure avec deux valeurs de paramètres différents:

....
choix = 0

while (choix!=3) :
    print("Mail SFR : tapez 1")
    print("Mail Free : tapez 2")
    print("Arreter : tapez 3")

    choix = int(input("Votre choix : "))

    if choix == 1 :
        AfficherLeMailChez("sfr")
    elif choix == 2 :
        AfficherLeMailChez("free")

Les valeurs des paramètres à l'appel ("sfr" et "free" dans notre exemple) sont les paramètres effectifs à ne pas confondre avec les paramètres formels: ce sont les noms apparaissant dans la liste des paramètres de la procédure. Dans notre exemple, il n'y a qu'un seul paramètre formel nommé operateur.

Exécution de la deuxième version

Voyons à présent comment tout cela fonctionne à l'exécution. Imaginons que l'utilisateur effectue le choix 2 ( Mail Free ).

  1. la procédure AfficherLeMailChez est appelée avec "free" comme paramètre effectif et la valeur de ce paramètre est transmise au paramètre formel de la manière suivante:
    • l'interpréteur Python crée une nouvelle variable locale nommée operateur
    • la valeur du paramètre effectif est affecté au paramètre formel. Dans notre cas, operateur prendra donc la valeur "free".
  2. les instructions contenues dans la procédure AfficherLeMailChez sont exécutées:
    • le prénom est lu et affecté à la variable locale prenom. Supposons que ce soit "eric".
    • le nom est lu et affecté à la variable locale nom. Supposons que ce soit "thirion".
    • l'instruction d'affichage de l'adresse mail est exécutée. Comme la valeur du paramètre formel operateur est "free", cela va provoquer l'affichage de l'adresse "eric.thirion@free.fr".
  3. rappelons que lorsqu'un sous-programme a fini de s'exécuter, le mécanisme de retour de sous-programme a lieu. C'est à ce moment que l'espace mémoire alloué aux paramètres et aux variables locales est libéré: elles "cessent d'exister ".

En fait, les paramètres formels d'un sous-programme se comportent comme des variables locales. Vous pouvez donc considérer que tout ce qui a été dit au sujet des variables locales s'applique également aux paramètres formels.

Remarques importantes :

Principes généraux

Déclaration d'une procédure

De manière générale, une procédure peut se déclarer de la manière suivante:


def Nom De La Procédure ( liste des paramètres ) :
    Bloc d'instructions

Rappelons que la première ligne est l'entête de la procédure.

Le bloc d'instructions qui suit est le corps de la procédure. Il contient les instructions à exécuter.

Liste des paramètres

La liste des paramètres peut être vide ou non. Mais dans tout les cas de figure, les parenthèses sont obligatoires. Une procédure sans paramètre s'écrira donc comme ceci:


def Nom De La Procédure (  ) :
    Bloc d'instructions

et s'il n'y a qu'un seul paramètre, comme dans l'exemple précédent:


def Nom De La Procédure (Nom du paramètre) :
    Bloc d'instructions


S'il y a plusieurs paramètres, ils sont séparés par des virgules:


def Nom De La Procédure (P1, P2, ...., Pn ) :
    Bloc d'instructions


Ecriture d'un appel de procédure
L'appel d'une procédure est formé du nom de cette procédure suivi d'une liste de paramètres effectifs entre parenthèses.

   Nom De La Procédure ( liste des paramètres effectifs )

Notez que les parenthèses sont obligatoires, même si la procédure ne possède pas de paramètres. Un appel de procédure sans paramètre s'écrit donc:


   Nom De La Procédure ( )

Dans l'exemple très simple que nous avons présenté, il n'y avait qu'un seul paramètre effectif. Mais de manière générale, il peut y en avoir plusieurs et de plus, ce ne sont pas forcément de simples littéraux mais des expressions. Pour définir la liste des paramètres effectifs de la manière la plus générale possible, nous dirons donc que c'est une liste d'expressions séparées par des virgules:


   expression1,...., expressionN 

Pour que l'appel de procédure ne génère pas d'erreur, il doit y avoir autant de paramètres effectifs que de paramètres formels .

Voici par exemple une procédure qui possède trois paramètres formels:

def FormerMail (p, n , o) :
    global mail
    mail = p + "." + n + "@" + o + ".fr"

Cette procédure forme une adresse mail à partir de trois paramètres:p (le prénom), n (le nom) et o (l'opérateur). Le résultat est stocké dans la variable globale mail.

En supposant que Prenom1, Prenom2 et Nom soient des variables de type chaine de caractères, elle pourrait être appelée de la manière suivante:


  FormerMail (Prenom1+"-"+Prenom2, Nom, "free")

Le premier paramètre effectif est une expression de type chaine de caractères, le deuxième une variable de type chaine de caractères et le troisième, un littéral de type chaine de caractères.

Exécution d'un appel de procédure
Principe du retour au sous-programme appelant

Un appel de procédure est toujours contenu dans le programme principal ou dans un autre sous-programme, que nous appelerons le sous-programme appelant.

RetourSousProg.jpg, 38kB

Lorsqu'un appel de procédure est exécuté, le processeur interrompt momentanément l'exécution du programme principal (ou du sous-programme appelant selon le cas) pour aller exécuter la procédure appelée. Après avoir exécuté les instructions de cette procédure, il reprend l'exécution du programme principal (ou du sous-programme appelant) à partir de l'instruction qui suivait l'appel .
Passage des paramètres et exécution de l'appel

Les paramètres formels d'un sous-programme peuvent être considérés comme des variables locales. Donc tout ce que nous avons dit sur les variables locales est également valable pour les paramètres. En particulier:

L'exécution d'un appel de procédure provoque les opérations suivantes: