k Les bases de la programmation en Python

Les bases de la programmation en Python

II - Programmer en Python

3/Fonctions

Qu'est-ce qu'une fonction ?

Une fonction est un bloc de code nommé. Une fonction correspond à un ensemble d’instructions créées pour effectuer une tâche précise, regroupées ensemble et qu’on va pouvoir exécuter autant de fois qu’on le souhaite en “l’appelant” avec son nom. Notez “qu’appeler” une fonction signifie exécuter les instructions qu’elle contient.

L’intérêt principal des fonctions se situe dans le fait qu’on va pouvoir appeler une fonction et donc exécuter les instructions qu’elle contient autant de fois qu’on le souhaite, ce qui constitue au final un gain de temps conséquent pour le développement d’un programme et ce qui nous permet de créer un code beaucoup plus clair.

Il existe deux grands “types” de fonctions en Python : les fonctions prédéfinies et les fonctions créées par l’utilisateur.

Les fonctions prédéfinies Python

Les fonction prédéfinies sont des fonctions déjà créées et mises à notre disposition par Python. Dans ce cours, nous avons déjà utilisé des fonctions prédéfinies comme la fonction print() ou la fonction type() par exemple.

Ici, je tiens à rappeler qu’en programmation rien n’est magique : la “programmation”… ne représente que des séries d’instruction programmées.

Lorsqu’on a utilisé print() pour afficher des données pour la première fois ou type() pour connaitre le type d’une donnée, on ne s’est pas posé la question de ce qu’il se passait en arrière plan.

En fait, ces deux fonctions sont des fonctions complexes et qui contiennent de nombreuses lignes d’instructions leur permettant d’accomplir une tâche précise : l’affichage d’un résultat ou la détermination du type d’une valeur en l’occurence.

Cette complexité nous est cachée : nous n’avons qu’à appeler nos fonctions pour qu’elles fassent leur travail et n’avons pas à écrire la série d’instructions qu’elles contiennent à chaque fois et c’est tout l’intérêt des fonctions.

Python, dans sa version 3.7.4, met à notre disposition quasiment 70 fonctions prédéfinies (sans compter les fonctions des modules ou extensions dont nous parlerons plus tard). Vous pouvez déjà trouver la liste ci-dessous. Nous serons amenés à utiliser la plupart d’entre elles dans ce cours ; nous les définirons à ce moment là. Considérez le tableau ci-dessous comme une simple référence.

Liste des fonction prédéfinies Python 3.7.4:

abs() delattr() hash()/td> memoryview() set()
all() dict() help() min() setattr()
any() dir() hex() next() slice()
ascii() divmod() id() object() sorted()
bin() enumerate() input() oct() staticmethod()
bool() eval() int() open() str()
breakpoint() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
globals() map() reversed() compile() __import()__
complex() hasattr() max() round()

Les fonction Python définies par l’utilisateur

En plus des fonction prédéfinies, Python nous laisse la possibilité de définir nos propres fonctions. Ces fonctions ne seront bien évidemment disponibles et utilisables que dans l’espace où elles ont été définies, c’est-à-dire uniquement au sein de nos scripts et non pas pour l’ensemble des développeurs utilisant Python.

On va vouloir créer nos propres fonctions Python lorsque nos programmes utilisent de manière répétées une même série d’instructions : plutôt que de réécrire ces instructions à chaque fois, autant utiliser une fonction !

Les fonctions vont aussi être de très bons outils d’abstraction lorsqu’on voudra distribuer notre code : on préférera souvent fournir des fonctions à utiliser aux autres développeurs plutôt que de les laisser se débrouiller avec des séries d’instructions “sauvages”.

Pour définir une nouvelle fonction en Python, nous allons utiliser le mot clef def qui sert à introduire une définition de fonction. Ce mot clef doit être suivi du nom de la fonction, d’une paire de parenthèses au sein desquelles on pourra fournir une liste de paramètres (nous reviendrons là dessus plus tard) et de : pour terminer la ligne comme ceci def ma_fonction():.

Le nom d’une fonction Python doit respecter les normes usuelles concernant les noms : un nom de fonction doit commencer par une lettre ou un underscore et ne contenir que des caractères alphanumériques classiques (pas d’accent ni de cédille ni aucun caractère spécial).

Notez que les noms de fonctions sont sensibles à la casse en Python, ce qui signifie que les fonctions ma_fonction(), Ma_fonction(), ma_FONCtion() et MA_FONCTION() par exemple seront des fonctions bien différentes pour Python.

Nous allons ensuite placer la liste des différentes instructions de notre fonction à la ligne suivant sa définition et en les indentant par rapport à la définition afin que Python comprenne que ces instructions appartiennent à notre fonction. Notez que la première instruction d’une fonction peut être une chaîne de caractères littérale qui sera alors utilisée comme chaine de documentation de la fonction.

Créons immédiatement deux fonctions bonjour() et BONJOUR() toutes simples dont le but va être d’afficher un message en exécutant elles-mêmes une fonction print(). On va faire cela comme cela :

Nous avons ici défini nos deux premières fonctions. Ces fonctions ne sont pas très utiles ici : elles se contentent simplement d’exécuter une fonction print() mais c’est déjà un bon début !

Maintenant que nos fonctions sont créées, nous allons devoir les appeler pour exécuter le code qu’elles contiennent. Pour cela, nous allons utiliser leur nom suivi d’un couple de parenthèses. On va pouvoir appeler nos fonctions autant de fois qu’on le souhaite dans notre script : c’est tout l’intérêt des fonctions !

Les paramètres et arguments des fonctions

Les fonctions que nous avons créées ci-dessus se contentent d’exécuter toujours la même fonction print() et donc de renvoyer toujours le même message.

Elles ne sont pas très utiles en l’état. Un autre aspect fondamental des fonctions est qu’elles vont pouvoir accepter des informations qui viennent de l’extérieur, c’est-à-dire qui sont externes à leur définition et qui vont les amener à produire des résultats différents. Souvent même, les fonctions vont avoir besoin qu’on leur passe des informations externes pour fonctionner normalement.

C’est par exemple le cas des fonctions print() et type() : ces deux fonctions permettent d’afficher un message et de déterminer le type d’une donnée. Pour afficher un message, print() va avoir besoin qu’on lui passe les données qu’elle doit afficher. De même, type() va avoir besoin qu’on lui fournisse la donnée dont elle doit déterminer le type.

Ces informations dont vont avoir besoin certaines fonctions pour fonctionner et qu’on va passer à nos fonctions entre le couple de parenthèses sont appelées des arguments ou des paramètres.

Pour rester très simple et très schématique ici, on parle de “paramètres” lorsqu’on définit une fonction, c’est-à-dire lorsqu’on indique dans la définition de la fonction que telle fonction a besoin d’une, de deux… informations pour fonctionner et on parle “d’arguments” pour désigner les valeurs effectivement passées à une fonction lorsqu’on l’utilise.

Illustrons cela immédiatement en reprenant et en modifiant notre fonction bonjour() afin qu’elle affiche “Bonjour “ suivi du nom de quelqu’un qui va lui être fourni ultérieurement. Pour réaliser cela, on va indiquer dans la définition de la fonction que celle-ci a besoin d’un paramètre pour fonctionner.

On peut donner n’importe quel nom à ce paramètre dans la définition puisque celui-ci sera dans tous les cas remplacé par la valeur effective passée lors de l’appel à la fonction. Pour une meilleure lisibilité, il est cependant conseillé de fournir des noms descriptifs et paramètres des fonctions. On peut par exemple l’appeler prenom dans notre cas :

Définition de paramètres et passage d'arguments aux fonctions Python

Expliquons ce code. On crée une nouvelle fonction bonjour() dont le rôle est d’afficher “Bonjour” suivi du prénom de quelqu’un. Pour que cela fonctionne, il va falloir lui passer un prénom lorsqu’on appelle notre fonction en argument de celle-ci.Dans la définition de la fonction, on va donc indiquer que notre fonction a besoin d’un paramètre pour fonctionner. Ici, on choisit le mot “prenom” pour définir notre paramètre. On aurait aussi bien pu choisir “toto”. Ensuite, dans le corps de notre fonction, on utilise une fonction print() qui va afficher “Bonjour” suivi du prénom qu’on aura indiqué lorsqu’on utilisera la fonction. Ici, je vous rappelle que le mot qu’on utilise comme paramètre lors de la définition de la fonction sera remplacé par la valeur passée en argument lors de l’appel à la fonction. On va donc utiliser notre paramètre dans print() afin que cette fonction affiche bien “Bonjour” suivi d’un prénom.

On utilise ensuite notre fonction plusieurs fois, en lui passant un prénom différent à chaque fois en argument. La valeur passée va se substituer au paramètre défini lors de la définition de la fonction.

Le code de notre fonction n’est cependant pas très optimisé ici : en effet, on utilise de la concaténation dans print() or la concaténation ne va fonctionner que si la valeur passée est bien une chaine de caractères. Si on passe un un chiffre en argument de bonjour(), Python renverra une erreur.

Ici, il va être plus efficace de passer le texte et l’argument comme deux arguments différents de print(). En effet, vous devez savoir que print() est capable d’accepter un nombre infini d’arguments qu’elle affichera à la suite. Cela résout notre problème de type de valeurs :