Tutoriel Python : comment utiliser *args et **kwargs ?

Table des matières

Introduction

Rappel sur les fonctions

La notion du « packing » et « unpacking »

Passer des arguments depuis une liste ou tuple

L’utilisation de l’opérateur * dans les paramètres d’une fonction (*args)

L’utilisation de l’opérateur ** dans les paramètres d’une fonction (**kwargs)

Ordre d’utilisation conjointe

Exercices d’application

Conclusion

Introduction :

Comme on l’a introduit dans le tutoriel des fonctions en Python, on a défini une fonction comme étant un code réutilisable pour effectuer des tâches répétitives afin de rendre le programme efficace et DRY.

Ainsi, pour effectuer ces tâches, on fait appel à la fonction qu’on a défini avec des arguments qui représentent les valeurs qu’on souhaite affecter à cette fonction.

Toutefois, en créant une fonction et en l’exécutant en lui passant des arguments, on reste limité aux nombres de paramètres qu’on a défini lors de sa création.

Dans ce tutoriel, on va traiter les notions du « packing » et du « unpacking », et par la suite, on va introduire les « *args » et les « **kwargs » et comment les affecter dans une fonction, tout en illustrant ces concepts dans des exemples et exercices.

Rappel sur les fonctions :

Rappel sur le rôle d’une fonction dans un programme :

Sur Python et comme dans tout langage de programmation, une fonction représente un bloc de code réutilisable contenant une tâche spécifique ou un groupe de tâches associées qui fonctionnent lors de l’appel de cette fonction.

L’utilité de créer une fonction consiste à éviter les redondances de code en utilisant une normalisation de données, et ainsi rend notre programme plus lisible et plus facile à maintenir et améliorer.

Définir et appeler une fonction :

Pour définir une fonction, on utilise le mot-clé def suivi par le nom de la fonction qui peut contenir ou pas un ou plusieurs paramètres entre parenthèses.

Exemple d’une fonction sans paramètres :

Syntaxe :

# Exemple d'une fonction sans paramètres :
# Définition de la fonction :
def direBonjour() :
print("Bonjour !")
# Appel de la fonction :
direBonjour()

Résultat d’exécution :

Exemple d’une fonction avec paramètres :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction :
def somme_3nbs(a, b, c) :
return a + b + c
# Appel de la fonction :
print("la somme de 4 et 9 et 6 est :", somme_3nbs(4, 9, 6))

Résultat d’exécution :

La notion du « packing » et « unpacking » :

Sur Python, l’opérateur * est connu comme étant un opérateur qui sert à réaliser des calculs de multiplication, ou de puissance, ou même, pour dupliquer une chaine de caractères.

Dans ce tutoriel, on va exploiter d’autres façons d’utilisation de cet opérateur qui sont le « packing » et le « unpacking ».

Le concept du « unpacking » (qui veut dire déballage ou dépaquetage en français) et du « packing » (qui veut dire emballage ou empaquetage en français), est de transformer un itérable en une succession d’arguments ou bien d’empaqueter des arguments en un itérable, en utilisant l’opérateur * pour des arguments non nommés, ou bien l’opérateur ** pour des arguments nommés.

Exemple du « unpacking » :

Syntaxe :

# Exemples d'utilisation de l'opérateur * :
# Exemple du "unpacking" d'une liste :
li = [5, 6, 8, 9]
print("le 'unpacking' de la liste [5, 6, 8, 9] est :", *li)
# Exemple du "unpacking" d'un tuple :
tu = (2, 20, 55, 3)
print("le 'unpacking' du tuple (2, 20, 55, 3) est :", *tu)

Résultat d’exécution :

Passer des arguments depuis une liste ou tuple :

Une des utilités de l’opérateur * est le « unpacking » (qui veut dire déballage ou dépaquetage en français), qui sert à transformer un itérable (tuple ou liste) en une succession d’arguments.

En prenant l’exemple précèdent, on essayera d’exécuter le résultat de la somme des nombres contenus dans une liste ou un tuple.

Exemple :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction :
def somme_3nbs(a, b, c) :
return a + b + c
# Appel de la fonction en utilisant une liste :
li = [1, 6, 9]
print("la somme des éléments de la liste est :", somme_3nbs(*li))
# Appel de la fonction en utilisant une liste :
tu = (15, 6, 99)
print("la somme des éléments du tuple est :", somme_3nbs(*tu))

Résultat d’exécution :

L’utilisation de l’opérateur * dans les paramètres d’une fonction (*args) :

Contexte :

Comme il est présenté dans l’exemple de la partie précédente, il est possible de passer plusieurs arguments à une fonction, mais, on est limité au nombre de paramètres qu’on a défini lors de la création de cette fonction, ainsi, il est impossible (dans l’exemple) de faire la somme de 4 ou 5 nombres.

Exemple de l’erreur :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction :
def somme_3nbs(a, b, c) :
return a + b + c
# Appel de la fonction :
print("la somme de 4 et 9 et 6 et 18 est :", somme_3nbs(4, 9, 6, 18))

Résultat d’exécution :

Résolution :

Ainsi pour faire le calcul de la somme de plusieurs arguments dans la fonction, on utilise l’operateur *, et par convention, on nomme le paramètre *args.

Exemple 1 :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre *args :
def somme(*args) :
return sum(args)
# Appel de la fonction :
print("la somme de 4 et 9 et 6 et 18 est :", somme(4 , 9 , 6 , 18))
print("la somme de 18 et 9 et 32 et 6 et 9 est :", somme(18 , 9 , 32 , 6 , 9))
print("la somme de 2 et 1 est :", somme(2 , 1))

Résultat d’exécution :

Exemple 2 :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre *args :
def somme(*args) :
return sum(args)
# Appel de la fonction :
nbrs1 = [4 , 9 , 6 , 18]
nbrs2 = [18 , 9 , 32 , 6 , 9]
nbrs3 = (2 , 1)
print("la somme de 4 et 9 et 6 et 18 est :", somme(*nbrs1))
print("la somme de 18 et 9 et 32 et 6 et 9 est :", somme(*nbrs2))
print("la somme de 2 et 1 est :", somme(*nbrs3))

Résultat d’exécution :

Remarque :

Notez bien que le mot-clé « args » est juste une préférence de notation et non pas indispensable pour réaliser ce procédé, on aura le même résultat en utilisant ( par exemple) la notation *nbrs, comme il est montré dans l’exemple suivant :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre *nbrs :
def somme(*nbrs) :
return sum(nbrs)
# Appel de la fonction :
print("la somme de 4 et 9 et 6 et 18 est :", somme(4 , 9 , 6 , 18))
print("la somme de 18 et 9 et 32 et 6 et 9 est :", somme(18 , 9 , 32 , 6 , 9))
print("la somme de 2 et 1 est :", somme(2 , 1))

Résultat d’exécution :

L’utilisation de l’opérateur ** dans les paramètres d’une fonction (**kwargs) :

L’opérateur * est utile pour des arguments non nommés tel qu’une liste ou un tuple d’argument, d’une autre part, l’opérateur ** est utile pour définir des arguments nommés comme dans un dictionnaire sur Python.

Exemple 1 :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre *args :
def presentation(**kwargs) :
for i in kwargs :
print("l'argument", i, "est :", kwargs[i])
# Appel de la fonction :
presentation(arg1 = "test 1", arg2 = "test 2", arg3 = "test 3")

Résultat d’exécution :

Exemple 2 :

On peut de même faire appel à la fonction en utilisant un dictionnaire :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre **kwargs :
def presentation(**kwargs) :
for i in kwargs :
print("l'argument", i, "est :", kwargs[i])
# Appel de la fonction :
dict = {"arg1" : "test 1", "arg2" : "test 2", "arg3" : "test 3"}
presentation(**dict)

Résultat d’exécution :

Remarque :

Notez bien que le mot-clé « kwargs » est juste une préférence de notation et non pas une nécessité pour réaliser ce procédé, on aura le même résultat en utilisant (par exemple) la notation **exemple, comme il est montré dans l’exemple suivant :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction en prenant comme paramètre **exemple :
def presentation(**exemple) :
for i in exemple :
print("l'argument", i, "est :", exemple[i])
# Appel de la fonction :
dict = {"arg1" : "test 1", "arg2" : "test 2", "arg3" : "test 3"}
presentation(**dict)

Résultat d’exécution :

Ordre d’utilisation conjointe :

Il est aussi possible d’utiliser de façon simultanée les *args et *kwargs, ainsi que des arguments normaux dans une fonction, tout en respectant un ordre lors de leurs création comme paramètres dans la définition de la fonction ; et cet ordre se manifeste en mettant en priorité les arguments normaux, par la suite les *args, et enfin les *kwargs en dernier.

Exemple :

Syntaxe :

# Exemple d'une fonction avec paramètres :
# Définition de la fonction :
def presentation(arg1, arg2, *args, **kwargs) :
print("les éléments du dictionnaire :")
cpt = 1
for i in kwargs :
print("\tl'élément", cpt, "est :", i,": ayant comme valeur :", kwargs[i])
cpt += 1
print("les éléments de la liste sont :", args)
print("les arguments définis directement sont :", arg1, "et", arg2)
# Appel de la fonction :
dict1 = {"clé 1" : "test 1", "clé 2" : "test 2", "clé 3" : "test 3"}
liste1 = ["élément 1", "élément 2", "élément 3", "élément 4", ]
arg1 = "'argument 1'"
arg2 = "'argument 2'"
presentation(arg1, arg2, *liste1, **dict1)

Résultat d’exécution :

Exercices d’application :

Exercice 1 :

Créez une fonction permettant de calculer le volume d’un parallélépipède, cette fonction doit accepter comme premier argument le type de solide (parallélépipède avec le mot clé « p » ou cube avec le mot clé « cu », cylindre avec le mot clé « cy », boule avec le mot clé « b »), et en deuxième argument un dictionnaire contenant les dimensions de la forme.

Indices :

  • Parallélépipède : Volume = hauteur x longueur x largeur.
  • Cube : hauteur = longueur = largeur = dim ; volume = dim3.
  • Cylindre : volume = pi x hauteur x rayon2.
  • Boule : Volume = (4/3) x pi x rayon3.

Solution :

Syntaxe :

import math
# création de la fonction :
def volume(forme, **dimensions) :
# Définir le volume pour un cube :
if forme == "cu" :
return dimensions["dim"]**3
# Définir le volume pour un parallélépipède :
elif forme == "p" :
return dimensions["hauteur"] * dimensions["longueur"] * dimensions["largeur"]
# Définir le volume pour une boule :
elif forme == "b" :
return (4/3) * math.pi * (dimensions["rayon"]**2)
# Définir le volume pour un cylindre :
elif forme == "cy" :
return math.pi * dimensions["hauteur"] * (dimensions["rayon"]**3)
# Test de la fonction :
cubedict = {"dim" : 12}
print("le volume du cube est :", volume("cu", **cubedict))
paradict = {"hauteur" : 12, "longueur" : 16, "largeur" : 10}
print("le volume du parallélépipède est :", volume("p", **paradict))
bouledict = {"rayon" : 5}
print("le volume de la boule est :", volume("b", **bouledict))
cyldict = {"hauteur" : 12, "rayon" : 16}
print("le volume du cylindre est :", volume("cy", **cyldict))

Résultat d’exécution :

Conclusion :

En finissant ce tutoriel contenant les notions du « packing » et « unpacking » et leur relation avec les itérables sur Python, ainsi que, le principe d’utilisation des mots-clé *args et **kwargs, vous êtes prêt pour créer des fonctions contenant un nombre variable d’arguments, ce qui vous permettra de faciliter la tâche dans votre parcours de programmation, et aussi, de voir un autre côté à manipuler dans votre codage.

Bonne chance à vous !

Et merci pour votre attention !

Article publié le 24 Octobre 2020par Ismail BOUZIANE