IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Apprendre à programmer avec Python

Apprendre programmer avec Python


prcdentsommairesuivant

Chapitre 7 : Fonctions originales

La programmation est l'art d'apprendre un ordinateur comment accomplir des tches qu'il n'tait pas capable de raliser auparavant. L'une des mthodes les plus intressantes pour y arriver consiste ajouter de nouvelles instructions au langage de programmation que vous utilisez, sous la forme de fonctions originales.

7.1. Dfinir une fonction

Les scripts que vous avez crits jusqu' prsent taient chaque fois trs courts, car leur objectif tait seulement de vous faire assimiler les premiers lments du langage. Lorsque vous commencerez dvelopper de vritables projets, vous serez confronts des problmes souvent fort complexes, et les lignes de programme vont commencer s'accumuler...

L'approche efficace d'un problme complexe consiste souvent le dcomposer en plusieurs sousproblmes plus simples qui seront tudis sparment (Ces sous-problmes peuvent ventuellement tre eux-mmes dcomposs leur tour, et ainsi de suite). Or il est important que cette dcomposition soit reprsente fidlement dans les algorithmes20 pour que ceux-ci restent clairs.

D'autre part, il arrivera souvent qu'une mme squence d'instructions doive tre utilise plusieurs reprises dans un programme, et on souhaitera bien videmment ne pas avoir la reproduire systmatiquement.

Les fonctions21 et les classes d'objets sont diffrentes structures de sous-programmes qui ont t imagines par les concepteurs des langages de haut niveau afin de rsoudre les difficults voques ci-dessus. Nous allons commencer par dcrire ici la dfinition de fonctions sous Python. Les objets et les classes seront examins plus loin.

Nous avons dj rencontr diverses fonctions pr-programmes. Voyons prsent comment en dfinir nous-mmes de nouvelles.

La syntaxe Python pour la dfinition d'une fonction est la suivante :

 
Sélectionnez

def nomDeLaFonction(liste de paramtres):
    ...
    bloc d'instructions
    ...
  • Vous pouvez choisir n'importe quel nom pour la fonction que vous crez, l'exception des mots rservs du langage22, et la condition de n'utiliser aucun caractre spcial ou accentu (le caractre soulign _ est permis). Comme c'est le cas pour les noms de variables, il vous est conseill d'utiliser surtout des lettres minuscules, notamment au dbut du nom (les noms commenant par une majuscule seront rservs aux classes que nous tudierons plus loin).
  • Comme les instructions if et while que vous connaissez dj, l'instruction def est une instruction compose. La ligne contenant cette instruction se termine obligatoirement par un double point, lequel introduit un bloc d'instructions que vous ne devez pas oublier d'indenter.
  • La liste de paramtres spcifie quelles informations il faudra fournir en guise d'arguments lorsque l'on voudra utiliser cette fonction (Les parenthses peuvent parfaitement rester vides si la fonction ne ncessite pas d'arguments).
  • Une fonction s'utilise pratiquement comme une instruction quelconque. Dans le corps d'un programme, un appel de fonction est constitu du nom de la fonction suivi de parenthses.
    Si c'est ncessaire, on place dans ces parenthses le ou les arguments que l'on souhaite transmettre la fonction. Il faudra en principe fournir un argument pour chacun des paramtres spcifis dans la dfinition de la fonction, encore qu'il soit possible de dfinir pour ces paramtres des valeurs par dfaut (voir plus loin).

20 On appelle algorithme la squence dtaille de toutes les oprations effectuer pour rsoudre un problme.

21 Il existe aussi dans d'autres langages des routines (parfois appels sous-programmes) et des procdures. Il n'existe pas de routines en Python. Quant au terme de fonction, il dsigne la fois les fonctions au sens strict (qui fournissent une valeur en retour), et les procdures (qui n'en fournissent pas).

22 La liste complte des mots rservs Python se trouve page 22.

7.1.1. Fonction simple sans paramtres

Pour notre premire approche concrte des fonctions, nous allons travailler nouveau en mode interactif. Le mode interactif de Python est en effet idal pour effectuer des petits tests comme ceux qui suivent. C'est une facilit que n'offrent pas tous les langages de programmation !

 
Sélectionnez

>>> def table7():
...     n = 1
...     while n <11 :
...         print n * 7,
...         n = n +1
...

En entrant ces quelques lignes, nous avons dfini une fonction trs simple qui calcule et affiche les 10 premiers termes de la table de multiplication par 7. Notez bien les parenthses23, le double point, et l'indentation du bloc d'instructions qui suit la ligne d'en-tte (c'est ce bloc d'instructions qui constitue le corps de la fonction proprement dite).

Pour utiliser la fonction que nous venons de dfinir, il suffit de l'appeler par son nom. Ainsi :

 
Sélectionnez

>>> table7()

provoque l'affichage de :

 
Sélectionnez

7 14 21 28 35 42 49 56 63 70 

Nous pouvons maintenant rutiliser cette fonction plusieurs reprises, autant de fois que nous le souhaitons. Nous pouvons galement l'incorporer dans la dfinition d'une autre fonction, comme dans l'exemple ci-dessous :

 
Sélectionnez

>>> def table7triple():
...     print 'La table par 7 en triple exemplaire :'
...     table7()
...     table7()
...     table7()
...

Utilisons cette nouvelle fonction, en entrant la commande :

 
Sélectionnez

>>> table7triple()

l'affichage rsultant devrait tre :

 
Sélectionnez

La table par 7 en triple exemplaire :
7 14 21 28 35 42 49 56 63 70
7 14 21 28 35 42 49 56 63 70
7 14 21 28 35 42 49 56 63 70

Une premire fonction peut donc appeler une deuxime fonction, qui elle-mme en appelle une troisime, etc. Au stade o nous sommes, vous ne voyez peut-tre pas encore trs bien l'utilit de tout cela, mais vous pouvez dj noter deux proprits intressantes :

  • Crer une nouvelle fonction vous offre l'opportunit de donner un nom tout un ensemble d'instructions. De cette manire, vous pouvez simplifier le corps principal d'un programme, en dissimulant un algorithme secondaire complexe sous une commande unique, laquelle vous pouvez donner un nom trs explicite, en franais si vous voulez.
  • Crer une nouvelle fonction peut servir raccourcir un programme, par limination des portions de code qui se rptent. Par exemple, si vous devez afficher la table par 7 plusieurs fois dans un mme programme, vous n'avez pas rcrire chaque fois l'algorithme qui accomplit ce travail.

Une fonction est donc en quelque sorte une nouvelle instruction personnalise, que vous ajoutez vous-mme librement votre langage de programmation.

23 Un nom de fonction doit toujours tre accompagn de parenthses, mme si la fonction n'utilise aucun paramtre.
Il en rsulte une convention d'criture qui stipule que dans un texte quelconque traitant de programmation d'ordinateur, un nom de fonction soit toujours accompagn d'une paire de parenthses vides.
Nous respecterons cette convention dans la suite de ce texte.

7.1.2. Fonction avec paramtre

Dans nos derniers exemples, nous avons dfini et utilis une fonction qui affiche les termes de la table par 7. Supposons prsent que nous voulions faire de mme avec la table par 9. Nous pouvons bien entendu rcrire entirement une nouvelle fonction pour cela. Mais si nous nous intressons plus tard la table par 13, il nous faudra encore recommencer. Ne serait-il donc pas plus intressant de dfinir une fonction qui soit capable d'afficher n'importe quelle table, la demande ?

Lorsque nous appellerons cette fonction, nous devrons bien videmment pouvoir lui indiquer quelle table nous souhaitons afficher. Cette information que nous voulons transmettre la fonction au moment mme o nous l'appelons s'appelle un argument. Nous avons dj rencontr plusieurs reprises des fonctions intgres qui utilisent des arguments. La fonction sin(a), par exemple, calcule le sinus de l'angle a. La fonction sin() utilise donc la valeur numrique de a comme argument pour effectuer son travail.

Dans la dfinition d'une telle fonction, il faut prvoir une variable particulire pour recevoir l'argument transmis. Cette variable particulire s'appelle un paramtre. On lui choisit un nom en respectant les mmes rgles de syntaxe que d'habitude (pas de lettres accentues, etc.), et on place ce nom entre les parenthses qui accompagnent la dfinition de la fonction.

Voici ce que cela donne dans le cas qui nous intresse :

 
Sélectionnez

>>> def table(base):
...     n = 1
...     while n <11 :
...         print n * base,
...         n = n +1

La fonction table() telle que dfinie ci-dessus utilise le paramtre base pour calculer les dix premiers termes de la table de multiplication correspondante.

Pour tester cette nouvelle fonction, il nous suffit de l'appeler avec un argument. Exemples :

 
Sélectionnez

>>> table(13)
13 26 39 52 65 78 91 104 117 130
 
>>> table(9)
9 18 27 36 45 54 63 72 81 90

Dans ces exemples, la valeur que nous indiquons entre parenthses lors de l'appel de la fonction (et qui est donc un argument) est automatiquement affecte au paramtre base. Dans le corps de la fonction, base joue le mme rle que n'importe quelle autre variable. Lorsque nous entrons la commande table(9), nous signifions la machine que nous voulons excuter la fonction table() en affectant la valeur 9 la variable base.

7.1.3. Utilisation d'une variable comme argument

Dans les 2 exemples qui prcdent, l'argument que nous avons utilis en appelant la fonction table() tait chaque fois une constante (la valeur 13, puis la valeur 9). Cela n'est nullement obligatoire. L'argument que nous utilisons dans l'appel d'une fonction peut tre une variable lui aussi, comme dans l'exemple ci-dessous. Analysez bien cet exemple, essayez-le concrtement, et dcrivez le mieux possible dans votre cahier d'exercices ce que vous obtenez, en expliquant avec vos propres mots ce qui se passe. Cet exemple devrait vous donner un premier aperu de l'utilit des fonctions pour accomplir simplement des tches complexes :

 
Sélectionnez

>>> a = 1
>>> while a <20:
...     table(a)
...     a = a +1
...

Remarque importante :

Dans l'exemple ci-dessus, l'argument que nous passons la fonction table() est le contenu de la variable a . A l'intrieur de la fonction, cet argument est affect au paramtre base, qui est une tout autre variable. Notez donc bien ds prsent que :

Le nom d'une variable que nous passons comme argument n'a rien voir avec le nom du paramtre correspondant dans la fonction.

Ces noms peuvent tre identiques si vous le voulez, mais vous devez bien comprendre qu'ils ne dsignent pas la mme chose (en dpit du fait qu'ils puissent contenir une valeur identique).


(7) Exercice :

7.1. Importez le module turtle pour pouvoir effectuer des dessins simples.

Vous allez dessiner une srie de triangles quilatraux de diffrentes couleurs.
Pour ce faire, dfinissez d'abord une fonction triangle() capable de dessiner un triangle d'une couleur bien dtermine (ce qui signifie donc que la dfinition de votre fonction doit comporter un paramtre pour recevoir le nom de cette couleur)

Utilisez ensuite cette fonction pour reproduire ce mme triangle en diffrents endroits, en changeant de couleur chaque fois.

7.1.4. Fonction avec plusieurs paramtres

La fonction table() est certainement intressante, mais elle n'affiche toujours que les dix premiers termes de la table de multiplication, alors que nous pourrions souhaiter qu'elle en affiche d'autres. Qu' cela ne tienne. Nous allons l'amliorer en lui ajoutant des paramtres supplmentaires, dans une nouvelle version que nous appellerons cette fois tableMulti() :

 
Sélectionnez

>>> def tableMulti(base, debut, fin):
...     print 'Fragment de la table de multiplication par', base, ':'
...     n = debut
...     while n <= fin :
...         print n, 'x', base, '=', n * base
...         n = n +1

Cette nouvelle fonction utilise donc trois paramtres : la base de la table comme dans l'exemple prcdent, l'indice du premier terme afficher, l'indice du dernier terme afficher.

Essayons cette fonction en entrant par exemple :

 
Sélectionnez

>>> tableMulti(8, 13, 17)

ce qui devrait provoquer l'affichage de :

 
Sélectionnez

Fragment de la table de multiplication par 8 :
13 x 8 = 104
14 x 8 = 112
15 x 8 = 120
16 x 8 = 128
17 x 8 = 136

Notes :

  • Pour dfinir une fonction avec plusieurs paramtres, il suffit d'inclure ceux-ci entre les parenthses qui suivent le nom de la fonction, en les sparant l'aide de virgules.
  • Lors de l'appel de la fonction, les arguments utiliss doivent tre fournis dans le mme ordre que celui des paramtres correspondants (en les sparant eux aussi l'aide de virgules). Le premier argument sera affect au premier paramtre, le second argument sera affect au second paramtre, et ainsi de suite.
  • A titre d'exercice, essayez la squence d'instructions suivantes et dcrivez dans votre cahier d'exercices le rsultat obtenu :
 
Sélectionnez

>>> t, d, f = 11, 5, 10
>>> while t<21:
...     tableMulti(t,d,f)
...     t, d, f = t +1, d +3, f +5
...

7.2. Variables locales, variables globales

Lorsque nous dfinissons des variables l'intrieur du corps d'une fonction, ces variables ne sont accessibles qu' la fonction elle-mme. On dit que ces variables sont des variables locales la fonction. C'est par exemple le cas des variables base, debut, fin et n dans l'exercice prcdent.

Chaque fois que la fonction tableMulti() est appele, Python rserve pour elle (dans la mmoire de l'ordinateur) un nouvel espace de noms24. Les contenus des variables base, debut, fin et n sont stocks dans cet espace de noms qui est inaccessible depuis l'extrieur de la fonction. Ainsi par exemple, si nous essayons d'afficher le contenu de la variable base juste aprs avoir effectu l'exercice ci-dessus, nous obtenons un message d'erreur :

 
Sélectionnez

>>> print base
Traceback (innermost last):
  File "<pyshell#8>", line 1, in ?
    print base
NameError: base

La machine nous signale clairement que le symbole base lui est inconnu, alors qu'il tait correctement imprim par la fonction tableMulti() elle-mme. L'espace de noms qui contient le symbole base est strictement rserv au fonctionnement interne de tableMulti(), et il est automatiquement dtruit ds que la fonction a termin son travail.

Les variables dfinies l'extrieur d'une fonction sont des variables globales. Leur contenu est visible de l'intrieur d'une fonction, mais la fonction ne peut pas le modifier. Exemple :

 
Sélectionnez

>>> def mask():
...     p = 20
...     print p, q
...
>>> p, q = 15, 38
>>> mask()
20 38
>>> print p, q
15 38

Analysons attentivement cet exemple :

Nous commenons par dfinir une fonction trs simple (qui n'utilise d'ailleurs aucun paramtre). A l'intrieur de cette fonction, une variable p est dfinie, avec 20 comme valeur initiale. Cette variable p qui est dfinie l'intrieur d'une fonction sera donc une variable locale.

Une fois termine la dfinition de la fonction, nous revenons au niveau principal pour y dfinir les deux variables p et q auxquelles nous attribuons les contenus 15 et 38. Ces deux variables dfinies au niveau principal seront donc des variables globales. Ainsi le mme nom de variable p a t utilis ici deux reprises, pour dfinir deux variables diffrentes : l'une est globale et l'autre est locale. On peut constater dans la suite de l'exercice que ces deux variables sont bel et bien des variables distinctes, indpendantes, obissant une rgle de priorit qui veut qu' l'intrieur d'une fonction (o elles pourraient entrer en comptition), ce sont les variables dfinies localement qui ont la priorit.

On constate en effet que lorsque la fonction mask() est lance, la variable globale q y est accessible, puisqu'elle est imprime correctement. Pour p, par contre, c'est la valeur attribue localement qui est affiche.

On pourrait croire d'abord que la fonction mask() a simplement modifi le contenu de la variable globale p (puisqu'elle est accessible). Les lignes suivantes dmontrent qu'il n'en est rien : en dehors de la fonction mask(), la variable globale p conserve sa valeur initiale.

Tout ceci peut vous paratre compliqu au premier abord. Vous comprendrez cependant trs vite combien il est utile que des variables soient ainsi dfinies comme tant locales, c'est--dire en quelque sorte confines l'intrieur d'une fonction. Cela signifie en effet que vous pourrez toujours utiliser quantits de fonctions sans vous proccuper le moins du monde des noms de variables qui y sont utilises : ces variables ne pourront en effet jamais interfrer avec celles que vous aurez vousmme dfinies par ailleurs.

Cet tat de choses peut toutefois tre modifi si vous le souhaitez. Il peut se faire par exemple que vous ayez dfinir une fonction qui soit capable de modifier une variable globale. Pour atteindre ce rsultat, il vous suffira d'utiliser l'instruction global. Cette instruction permet d'indiquer - l'intrieur de la dfinition d'une fonction - quelles sont les variables traiter globalement.

Dans l'exemple ci-dessous, la variable a utilise l'intrieur de la fonction monter() est non seulement accessible, mais galement modifiable, parce qu'elle est signale explicitement comme tant une variable qu'il faut traiter globalement. Par comparaison, essayez le mme exercice en supprimant l'instruction global : la variable a n'est plus incrmente chaque appel de la fonction.

 
Sélectionnez

>>> def monter():
...     global a
...     a = a+1
...     print a
...
>>> a = 15
>>> monter()
16
>>> monter()
17
>>>

24 Ce concept d'espace de noms sera approfondi progressivement. Vous apprendrez galement plus loin que les fonctions sont en fait des objets dont on cre chaque fois une nouvelle instance lorsqu'on les appelle.

7.3. Vraies fonctions et procdures

Pour les puristes, les fonctions que nous avons dcrites jusqu' prsent ne sont pas tout fait des fonctions au sens strict, mais plus exactement des procdures25. Une vraie fonction (au sens strict) doit en effet renvoyer une valeur lorsqu'elle se termine. Une vraie fonction peut s'utiliser la droite du signe gale dans des expressions telles que y = sin(a). On comprend aisment que dans cette expression, la fonction sin() renvoie une valeur (le sinus de l'argument s) qui est directement affecte la variable y.

Commenons par un exemple extrmement simple :

 
Sélectionnez

>>> def cube(w):
...     return w*w*w
...

L'instruction return dfinit ce que doit tre la valeur renvoye par la fonction. En l'occurrence, il s'agit du cube de l'argument qui a t transmis lors de l'appel de la fonction. Exemple :

 
Sélectionnez

>>> b = cube(9)
>>> print b
729

A titre d'exemple un peu plus labor, nous allons maintenant modifier quelque peu la fonction table() sur laquelle nous avons dj pas mal travaill, afin qu'elle renvoie elle aussi une valeur. Cette valeur sera en l'occurrence une liste (la liste des dix premiers termes de la table de multiplication choisie). Voil donc une occasion de reparler des listes. Nous en profiterons pour apprendre dans la foule encore un nouveau concept :

 
Sélectionnez

>>> def table(base):
...     result = []                   # result est d'abord une liste vide
...     n = 1
...     while n < 11:
...         b = n * base
...         result.append(b)          # ajout d'un terme  la liste
...         n = n +1                  # (voir explications ci-dessous)
...     return result
...

Pour tester cette fonction, nous pouvons entrer par exemple :

 
Sélectionnez

>>> ta9 = table(9)

Ainsi nous affectons la variable ta9 les dix premiers termes de la table de multiplication par 9, sous la forme d'une liste :

 
Sélectionnez

>>> print ta9
[9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
>>> print ta9[0]
9
>>> print ta9[3]
36
>>> print ta9[2:5]
[27, 36, 45]
>>>

(Rappel : le premier lment d'une liste correspond l'indice 0)

Notes:

  • Comme nous l'avons vu dans l'exemple prcdent, l'instruction return dfinit ce que doit tre la valeur renvoye par la fonction. En l'occurrence, il s'agit ici du contenu de la variable result, c'est--dire la liste des nombres gnrs par la fonction26.

  • L'instruction result.append(b) est notre second exemple de l'utilisation d'un concept important sur lequel nous reviendrons encore abondamment par la suite : dans cette instruction, nous appliquons la mthode append() l'objet result.

    Nous prciserons petit petit ce qu'il faut entendre par objet en programmation. Pour l'instant, admettons simplement que ce terme trs gnral s'applique notamment aux listes de Python. Une mthode n'est en fait rien d'autre qu'une fonction (que vous pouvez d'ailleurs reconnatre comme telle la prsence des parenthses), mais une fonction qui est associe un objet. Elle fait partie de la dfinition de cet objet, ou plus prcisment de la classe particulire laquelle cet objet appartient (nous tudierons ce concept de classe plus tard).

    Mettre en oeuvre une mthode associe un objet consiste en quelque sorte faire fonctionner cet objet d'une manire particulire. Par exemple, on met en oeuvre la mthode methode4() d'un objet objet3, l'aide d'une instruction du type : objet3.methode4() , c'est-dire le nom de l'objet, puis le nom de la mthode, relis l'un l'autre par un point. Ce point joue un rle essentiel : on peut le considrer comme un vritable oprateur.

  • Dans notre exemple, nous appliquons donc la mthode append() l'objet result. Sous Python, les listes constituent un type particulier d'objets, auxquels on peut effectivement appliquer toute une srie de mthodes. En l'occurrence, la mthode append() est donc une fonction spcifique des listes, qui sert leur ajouter un lment par la fin. L'lment ajouter est transmis entre les parenthses, comme tout argument qui se respecte.

    Remarque :
    Nous aurions obtenu un rsultat similaire si nous avions utilis la place de cette instruction une expression telle que result = result + [b] . Cette faon de procder est cependant moins rationnelle et moins efficace, car elle consiste redfinir chaque itration de la boucle une nouvelle liste result, dans laquelle la totalit de la liste prcdente est chaque fois recopie avec ajout d'un lment supplmentaire.
    Lorsque l'on utilise la mthode append(), par contre, l'ordinateur procde bel et bien une modification de la liste existante (sans la recopier dans une nouvelle variable). Cette technique est prfrable, car elle mobilise moins lourdement les ressources de l'ordinateur et elle est plus rapide (surtout lorsqu'il s'agit de traiter des listes volumineuses).

  • Il n'est pas du tout indispensable que la valeur renvoye par une fonction soit affecte une variable (comme nous l'avons fait jusqu'ici dans nos exemples par souci de clart).
    Ainsi, nous aurions pu tester les fonction cube() et table() en entrant les commandes :

     
    Sélectionnez
    
    >>> print cube(9)
    >>> print table(9)
    >>> print table(9)[3]
    

    ou encore plus simplement encore :

     
    Sélectionnez
    
    >>> cube(9)                             ... etc.
    

25 Dans certains langages de programmation, les fonctions et les procdures sont dfinies l'aide d'instructions diffrentes. Python utilise la mme instruction def pour dfinir les unes et les autres.

26 return peut galement tre utilis sans aucun argument, l'intrieur d'une fonction, pour provoquer sa fermeture immdiate. La valeur retourne dans ce cas est l'objet None (objet particulier, correspondant "rien").

7.4. Utilisation des fonctions dans un script

Pour cette premiere approche des fonctions, nous n'avons utilise jusqu'ici que le mode interactif de l'interpreteur Python.

Il est bien evident que les fonctions peuvent aussi s'utiliser dans des scripts. Veuillez donc essayer vous-meme le petit programme ci-dessous, lequel calcule le volume d'une sphere a l'aide de la formule que vous connaissez certainement : V=4/3 πR3

 
Sélectionnez

def cube(n):
    return n**3
 
def volumeSphere(r):
    return 4 * 3.1416 * cube(r) / 3
 
r = input('Entrez la valeur du rayon : ')
print 'Le volume de cette sphre vaut', volumeSphere(r)

Notes :

A bien y regarder, ce programme comporte trois parties : les deux fonctions cube() et volumeSphere(), et ensuite le corps principal du programme.

Dans le corps principal du programme, il y a un appel de la fonction volumeSphere().

A l'intrieur de la fonction volumeSphere(), il y a un appel de la fonction cube().

Notez bien que les trois parties du programme ont t disposes dans un certain ordre : d'abord la dfinition des fonctions, et ensuite le corps principal du programme. Cette disposition est ncessaire, parce que l'interprteur excute les lignes d'instructions du programme l'une aprs l'autre, dans l'ordre o elles apparaissent dans le code source. Dans le script, la dfinition des fonctions doit donc prcder leur utilisation.

Pour vous en convaincre, intervertissez cet ordre (en plaant par exemple le corps principal du programme au dbut), et prenez note du type de message d'erreur qui est affich lorsque vous essayez d'excuter le script ainsi modifi.

En fait, le corps principal d'un programme Python constitue lui-mme une entit un peu particulire, qui est toujours reconnue dans le fonctionnement interne de l'interprteur sous le nom rserv __main__ (le mot main signifie principal , en anglais. Il est encadr par des caractres soulign en double, pour viter toute confusion avec d'autres symboles). L'excution d'un script commence toujours avec la premire instruction de cette entit __main__, o qu'elle puisse se trouver dans le listing. Les instructions qui suivent sont alors excutes l'une aprs l'autre, dans l'ordre, jusqu'au premier appel de fonction. Un appel de fonction est comme un dtour dans le flux de l'excution : au lieu de passer l'instruction suivante, l'interprteur excute la fonction appele, puis revient au programme appelant pour continuer le travail interrompu. Pour que ce mcanisme puisse fonctionner, il faut que l'interprteur ait pu lire la dfinition de la fonction avant l'entit __main__, et celle-ci sera donc place en gnral la fin du script.

Dans notre exemple, l'entit __main__ appelle une premire fonction qui elle-mme en appelle une deuxime. Cette situation est trs frquente en programmation. Si vous voulez comprendre correctement ce qui se passe dans un programme, vous devez donc apprendre lire un script, non pas de la premire la dernire ligne, mais plutt en suivant un cheminement analogue ce qui se passe lors de l'excution de ce script. Cela signifie concrtement que vous devrez souvent analyser un script en commenant par ses dernires lignes !

7.5. Modules de fonctions

Afin que vous puissiez mieux comprendre encore la distinction entre la dfinition d'une fonction et son utilisation au sein d'un programme, nous vous suggrons de placer frquemment vos dfinitions de fonctions dans un module Python, et le programme qui les utilise dans un autre.

Exemple :

On souhaite raliser la srie de dessins ci-dessous, l'aide du module turtle :

Image non disponible

crivez les lignes de code suivantes, et sauvegardez-les dans un fichier auquel vous donnerez le nom dessins_tortue.py :

 
Sélectionnez

from turtle import *
 
def carre(taille, couleur):
    "fonction qui dessine un carr de taille et de couleur dtermines"
    color(couleur)
    c =0
    while c <4:
        forward(taille)
        right(90)
        c = c +1

Vous pouvez remarquer que la dfinition de la fonction carre() commence par une chane de caractres. Cette chane ne joue aucun rle fonctionnel dans le script : elle est traite par Python comme un simple commentaire, mais qui est mmoris part dans un systme de documentation interne automatique, lequel pourra ensuite tre exploit par certains utilitaires et diteurs "intelligents".

Si vous programmez dans l'environnement IDLE, par exemple, vous verrez apparatre cette chane documentaire dans une "bulle d'aide", chaque fois que vous ferez appel aux fonctions ainsi documentes.

En fait, Python place cette chane dans une variable spciale dont le nom est __doc__ (le mot "doc" entour de deux paires de caractres "soulign"), et qui est associe l'objet fonction comme tant l'un de ses attributs (Vous en apprendrez davantage au sujet de ces attributs lorsque nous aborderons les classes d'objets. Cf. page 154).

Ainsi, vous pouvez vous-mme retrouver la chane de documentation d'une fonction quelconque en affichant le contenu de cette variable. Exemple :

 
Sélectionnez

>>> def essai():
...     "Cette fonction est bien documente mais ne fait presque rien."
...     print "rien  signaler"
>>> essai()
rien  signaler
>>> print essai.__doc__

Cette fonction est bien documente mais ne fait presque rien.

Prenez donc la peine d'incorporer une telle chane explicative dans toutes vos dfinitions de fonctions futures : il s'agit l d'une pratique hautement recommandable.

Le fichier que vous aurez cr ainsi est dornavant un vritable module de fonctions Python, au mme titre que les modules turtle ou math que vous connaissez dj. Vous pouvez donc l'utiliser dans n'importe quel autre script, comme celui-ci, par exemple, qui effectuera le travail demand :

 
Sélectionnez

from dessins_tortue import *
 
up()                       # relever le crayon
goto(-150, 50)             # reculer en haut  gauche
 
# dessiner dix carrs rouges, aligns :
i = 0
while i < 10:
    down()                 # abaisser le crayon
    carre(25, 'red')       # tracer un carr
    up()                   # relever le crayon
    forward(30)            # avancer + loin
    i = i +1
 
a = input()                # attendre

Note :

Vous pouvez priori nommer vos modules de fonctions comme bon vous semble. Sachez cependant qu'il vous sera impossible d'importer un module si son nom est l'un des 29 mots rservs Python signals la page 22, car le nom du module import deviendrait une variable dans votre script, et les mots rservs ne peuvent pas tre utiliss comme noms de variables. Rappelons aussi qu'il vous faut viter de donner vos modules - et tous vos scripts en gnral - le mme nom que celui d'un module Python prexistant, sinon vous devez vous attendre des conflits. Par exemple, si vous donnez le nom turtle.py un exercice dans lequel vous avez plac une instruction d'importation du module turtle, c'est l'exercice lui-mme que vous allez importer !

Image non disponible

Exercices :

7.2. Dfinissez une fonction ligneCar(n, ca) qui renvoie une chane de n caractres ca.

7.3. Dfinissez une fonction surfCercle(R). Cette fonction doit renvoyer la surface (l'aire) d'un cercle dont on lui a fourni le rayon R en argument. Par exemple, l'excution de l'instruction :
print surfCercle(2.5) doit donner le rsultat 19.635

7.4. Dfinissez une fonction volBoite(x1,x2,x3) qui renvoie le volume d'une bote paralllipipdique dont on fournit les trois dimensions x1, x2, x3 en arguments. Par exemple, l'excution de l'instruction :
print volBoite(5.2, 7.7, 3.3) doit donner le rsultat : 132.13

7.5. Dfinissez une fonction maximum(n1,n2,n3) qui renvoie le plus grand de 3 nombres n1, n2, n3 fournis en arguments. Par exemple, l'excution de l'instruction : print maximum(2,5,4) doit donner le rsultat : 5

7.6. Compltez le module de fonctions graphiques dessins_tortue.py dcrit la page 73. Commencez par ajouter un paramtre angle la fonction carre(), de manire ce que les carrs puissent tre tracs dans diffrentes orientations.
Dfinissez ensuite une fonction triangle(taille, couleur, angle) capable de dessiner un triangle quilatral d'une taille, d'une couleur et d'une orientation bien dtermines.
Testez votre module l'aide d'un programme qui fera appel ces fonctions plusieurs reprises, avec des arguments varis pour dessiner une srie de carrs et de triangles :

Image non disponible

7.7. Ajoutez au module de l'exercice prcdent une fonction etoile5() spcialise dans le dessin d'toiles 5 branches. Dans votre programme principal, insrez une boucle qui dessine une range horizontale de de 9 petites toiles de tailles varies :

Image non disponible

7.8. Ajoutez au module de l'exercice prcdent une fonction etoile6() capable de dessiner une toile 6 branches, elle-mme constitue de deux triangles quilatraux imbriqus. Cette nouvelle fonction devra faire appel la fonction triangle() dfinie prcdemment.
Votre programme principal dessinera galement une srie de ces toiles :

Image non disponible
Image non disponible

7.9. Dfinissez une fonction compteCar(ca,ch) qui renvoie le nombre de fois que l'on rencontre le caractre ca dans la chane de caractres ch. Par exemple, l'excution de l'instruction :
print compteCar('e','Cette phrase est un exemple') doit donner le rsultat : 7

7.10. Dfinissez une fonction indexMax(liste) qui renvoie l'index de l'lment ayant la valeur la plus leve dans la liste transmise en argument. Exemple d'utilisation :

 
Sélectionnez

serie = [5, 8, 2, 1, 9, 3, 6, 7]
print indexMax(serie)
4

7.11. Dfinissez une fonction nomMois(n) qui renvoie le nom du ne mois de l'anne. Par exemple, l'excution de l'instruction :
print nomMois(4) doit donner le rsultat : Avril

7.12. Dfinissez une fonction inverse(ch) qui permette d'inverser les l'ordre des caractres d'une chane quelconque. (La chane inverse sera renvoye au programme appelant).

7.13. Dfinissez une fonction compteMots(ph) qui renvoie le nombre de mots contenus dans la phrase ph (On considre comme mots les ensembles de caractres inclus entre des espaces).

7.6. Typage des paramtres

Vous avez appris que le typage des variables sous Python est un typage dynamique, ce qui signifie que le type d'une variable est dfini au moment o on lui affecte une valeur. Ce mcanisme fonctionne aussi pour les paramtres d'une fonction. Le type d'un paramtre sera le mme que celui de l'argument qui aura t transmis la fonction. Exemple :

 
Sélectionnez

>>> def afficher3fois(arg):
...     print arg, arg, arg
...
 
>>> afficher3fois(5)
5 5 5
 
>>> afficher3fois('zut')
zut zut zut
 
>>> afficher3fois([5, 7])
[5, 7] [5, 7] [5, 7]
 
>>> afficher3fois(6**2)
36 36 36

Dans cet exemple, vous pouvez constater que la mme fonction afficher3fois() accepte dans tous les cas l'argument qu'on lui transmet, que cet argument soit un nombre, une chane de caractres, une liste, ou mme une expression. Dans ce dernier cas, Python commence par valuer l'expression, et c'est le rsultat de cette valuation qui est transmis comme argument la fonction.

7.7. Valeurs par dfaut pour les paramtres

Dans la dfinition d'une fonction, il est possible (et souvent souhaitable) de dfinir un argument par dfaut pour chacun des paramtres. On obtient ainsi une fonction qui peut tre appele avec une partie seulement des arguments attendus. Exemples :

 
Sélectionnez

>>> def politesse(nom, vedette ='Monsieur'):
...     print "Veuillez agrer ,", vedette, nom, ", mes salutations distingues."
...
 
>>> politesse('Dupont')
Veuillez agrer , Monsieur Dupont , mes salutations distingues.
 
>>> politesse('Durand', 'Mademoiselle')
Veuillez agrer , Mademoiselle Durand , mes salutations distingues.

Lorsque l'on appelle cette fonction en ne lui fournissant que le premier argument, le second reoit tout de mme une valeur par dfaut. Si l'on fournit les deux arguments, la valeur par dfaut pour le deuxime est tout simplement ignore.

Vous pouvez dfinir une valeur par dfaut pour tous les paramtres, ou une partie d'entre eux seulement. Dans ce cas, cependant, les paramtres sans valeur par dfaut doivent prcder les autres dans la liste. Par exemple, la dfinition ci-dessous est incorrecte :

 
Sélectionnez

>>> def politesse(vedette ='Monsieur', nom):

Autre exemple :

 
Sélectionnez

>>> def question(annonce, essais =4, please ='Oui ou non, s.v.p.!'):
...     while essais >0:
...         reponse = raw_input(annonce)
...         if reponse in ('o', 'oui','O','Oui','OUI'):
...             return 1
...         if reponse in ('n','non','N','Non','NON'):
...             return 0
...         print please
...         essais = essais-1
...
>>>

Cette fonction peut tre appele de diffrentes faons, telles par exemple :

 
Sélectionnez

rep = question('Voulez-vous vraiment terminer ? ') 

ou bien :

 
Sélectionnez

rep = question('Faut-il effacer ce fichier ? ', 3)

ou mme encore :

 
Sélectionnez

rep = question('Avez-vous compris ? ', 2, 'Rpondez par oui ou par non !')	

(Prenez la peine d'essayer et de dcortiquer cet exemple)

7.8. Arguments avec tiquettes

Dans la plupart des langages de programmation, les arguments que l'on fournit lors de l'appel d'une fonction doivent tre fournis exactement dans le mme ordre que celui des paramtres qui leur correspondent dans la dfinition de la fonction.

Python autorise cependant une souplesse beaucoup plus grande. Si les paramtres annoncs dans la dfinition de la fonction ont reu chacun une valeur par dfaut, sous la forme dj dcrite cidessus, on peut faire appel la fonction en fournissant les arguments correspondants dans n'importe quel ordre, la condition de dsigner nommment les paramtres correspondants.
Exemple :

 
Sélectionnez

>>> def oiseau(voltage=100, etat='allum', action='danser la java'):
...     print 'Ce perroquet ne pourra pas', action
...     print 'si vous le branchez sur', voltage, 'volts !'
...     print "L'auteur de ceci est compltement", etat
...
 
>>> oiseau(etat='givr', voltage=250, action='vous approuver')
Ce perroquet ne pourra pas vous approuver
si vous le branchez sur 250 volts !
L'auteur de ceci est compltement givr
 
>>> oiseau()
Ce perroquet ne pourra pas danser la java
si vous le branchez sur 100 volts !
L'auteur de ceci est compltement allum

Exercices :

7.14. Modifiez la fonction volBoite(x1,x2,x3) que vous avez dfinie dans un exercice prcdent, de manire ce qu'elle puisse tre appele avec trois, deux, un seul, ou mme aucun argument. Utilisez pour ceux ci des valeurs par dfaut gales ) 10.
Par exemple :
print volBoite() doit donner le rsultat : 1000
print volBoite(5.2) doit donner le rsultat : 520.0
print volBoite(5.2, 3) doit donner le rsultat : 156.0

7.15. Modifiez la fonction volBoite(x1,x2,x3) ci-dessus de manire ce qu'elle puisse tre appele avec un, deux, ou trois arguments. Si un seul est utilis, la bote est considre comme cubique (l'argument tant l'arte de ce cube). Si deux sont utiliss, la bote est considre comme un prisme base carre. (Dans ce cas le premier argument est le ct du carr, et le second la hauteur du prisme). Si trois arguments sont utiliss, la bote est considre comme un paralllpipde. Par exemple :
print volBoite() doit donner le rsultat : -1 (→ indication d'une erreur).
print volBoite(5.2) doit donner le rsultat : 140.608
print volBoite(5.2, 3) doit donner le rsultat : 81.12
print volBoite(5.2, 3, 7.4) doit donner le rsultat : 115.44

7.16. Dfinissez une fonction changeCar(ch,ca1,ca2,debut,fin) qui remplace tous les caractres ca1 par des caractres ca2 dans la chane de caractres ch, partir de l'indice debut et jusqu' l'indice fin, ces deux derniers arguments pouvant tre omis (et dans ce cas la chane est traite d'une extrmit l'autre). Exemples de la fonctionnalit attendue :

 
Sélectionnez

>>> phrase = 'Ceci est une toute petite phrase.'
>>> print changeCar(phrase, ' ', '*')
Ceci*est*une*toute*petite*phrase.
>>> print changeCar(phrase, ' ', '*', 8, 12)
Ceci est*une*toute petite phrase.
>>> print changeCar(phrase, ' ', '*', 12)
Ceci est une*toute*petite*phrase.
>>> print changeCar(phrase, ' ', '*', fin = 12)
Ceci*est*une*toute petite phrase.

7.17. Dfinissez une fonction eleMax(liste,debut,fin) qui renvoie l'lment ayant la plus grande valeur dans la liste transmise. Les deux arguments debut et fin indiqueront les indices entre lesquels doit s'exercer la recherche, et chacun d'eux pourra tre omis (comme dans l'exercice prcdent). Exemples de la fonctionnalit attendue :

 
Sélectionnez

>>> serie = [9, 3, 6, 1, 7, 5, 4, 8, 2]
>>> print eleMax(serie)
9
>>> print eleMax(serie, 2, 5)
7
>>> print eleMax(serie, 2)
8
>>> print eleMax(serie, fin =3, debut =1)
6
 

prcdentsommairesuivant

Licence Creative Commons
Le contenu de cet article est rédigé par Gérard Swinnen et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.