Créer des fonctions acceptant un nombre variable d’arguments
Dans la leçon précédente, nous avons défini ce qu’étaient des paramètres et des arguments. Nous avons créé une fonction bonjour()
qui avait besoin qu’on lui passe un argument pour fonctionner comme ceci :
Cette définition impose qu’on passe un et un seul argument à notre fonction pour qu’elle fonctionne : si on tente de l’appeler sans argument ou en lui passant plusieurs arguments Python renverra une erreur.
Dans certaines situations, nous voudrons créer des fonctions plus flexibles qui pourront accepter un nombre variable d’arguments. Cela peut être utile si on souhaite créer une fonction de calcul de somme par exemple qui devra additionner les différents arguments passés sans limite sur le nombre d’arguments et sans qu’on sache à priori combien de valeurs vont être additionnées.
En Python, il existe deux façons différentes de créer des fonctions qui acceptent un nombre variable d’arguments. On peut :
- Définir des valeurs de paramètres par défaut lors de la définition d’une fonction ;
- Utiliser une syntaxe particulière permettant de passer un nombre arbitraire d’arguments.
Préciser des valeurs par défaut pour les paramètres d’une fonction
On va déjà pouvoir préciser des valeurs par défaut pour nos paramètres. Comme leur nom l’indique, ces valeurs seront utilisées par défaut lors d’un appel à la fonction si aucune valeur effective (si aucun argument) n’est passée à la place.
Utiliser des valeurs par défaut pour les paramètres de fonctions permet donc aux utilisateurs d’appeler cette fonction en passant en omettant de passer les arguments relatifs aux paramètres possédant des valeurs par défaut.
On va pouvoir définir des fonctions avec des paramètres sans valeur et des paramètres avec des valeurs par défaut. Attention cependant : vous devez bien comprendre qu’ici, si on omet de passer des valeurs lors de l’appel à la fonction, Python n’a aucun moyen de savoir quel argument est manquant. Si 1, 2, etc. arguments sont passés, ils correspondront de facto au premier, aux premier et deuxième, etc. paramètres de la définition de fonction.
Pour cette raison, on placera toujours les paramètres sans valeur par défaut au début et ceux avec valeurs par défaut à la fin afin que le arguments passés remplacent en priorité les paramètres sans valeur.
Si on souhaite s’assurer que les valeurs passées à une fonction vont bien correspondre à tel ou tel paramètre, on peut passer à nos fonctions des arguments nommés. Un argument nommé est un argument qui contient le nom d’un paramètre présent dans la définition de la fonction suivi de la valeur qu’on souhaite passer comme ceci : argument = valeur
.
On va pouvoir passer les arguments nommés dans n’importe quel ordre puisque Python pourra faire le lien grâce au nom avec les arguments attendus par notre fonction. Notez cependant qu’il faudra ici passer les arguments nommés en dernier, après les arguments sans nom. Par ailleurs, aucun argument ne peut recevoir de valeur plus d’une fois. Faites donc bien attention à ne pas passer une valeur à un argument sans le nommer puis à repasser cette valeur en le nommant par inattention.
Passer un nombre arbitraire d’arguments avec *args et **kwargs
La syntaxe *args
(remplacez “args” par ce que vous voulez) permet d’indiquer lors de la définition d’une fonction que notre fonction peut accepter un nombre variable d’arguments. Ces arguments sont intégrés dans un tuple. On va pouvoir préciser 0, 1 ou plusieurs paramètres classiques dans la définition de la fonction avant la partie variable.
Ici, on utilise une boucle for
pour itérer parmi les arguments : tant que des valeurs sont trouvées, elles sont ajoutées à la valeur de s
. Dès qu’on arrive à court d’arguments, on print()
le résultat.
De façon alternative, la syntaxe **kwargs
(remplacez “kwargs” par ce que vous voulez) permet également d’indiquer que notre fonction peut recevoir un nombre variable d’arguments mais cette fois-ci les arguments devront être passés sous la forme d’un dictionnaire Python.
Dans cette exemple, j’utilise la méthode Python items()
dont le rôle est de récupérer les différentes paires clefs : valeurs d’un dictionnaire. Nous reparlerons des méthodes lorsque nous aborderons l’orienté objet. Pour le moment, vous pouvez considérer qu’une méthode est l’équivalent d’une fonction.
Séparer des données pour les passer à une fonction
Les syntaxes *args
et **kwargs
peuvent être utilisées pour réaliser les opérations inverse de celles présentés ci-dessus, à savoir séparer des données composites pour passer les valeurs ou éléments de ces données un à un en arguments des fonctions.
On, utilisera la syntaxe *args
pour séparer les arguments présents dans une liste ou un tuple et la syntaxe **kwargs
pour séparer les arguments présents dans un dictionnaire et fournir des arguments nommés à une fonction.