Que sont * args et ** kwargs en Python?

Les fonctions sont la vie. Non? Si vous venez de commencer à apprendre Python, peu importe si c'est votre premier langage de programmation, ou si vous êtes arrivé à Python à partir d'un autre langage, alors vous savez déjà que le nombre de paramètres dans la déclaration de fonction correspond au nombre d'arguments que la fonction passe lors de son appel.



Ce sont les bases. C'est ce qui aide les gens à comprendre le monde qui les entoure. Mais l'énoncé «le nombre de paramètres est égal au nombre d'arguments» met une bombe à retardement dans la tête du débutant, qui se déclenche après avoir **kwargs les mystérieuses constructions *args ou **kwargs dans la déclaration de fonction.

Ne laissez aucun badge vous entraîner dans la stupeur. Il n'y a rien d'archaïque ici. En général, si ces modèles ne vous sont pas familiers, je vous suggère de les traiter.

Arguments positionnels et nommés


Afin de gérer *args et **kwargs , nous devons maîtriser les concepts d'arguments positionnels et nommés.

Tout d'abord, parlons de leurs différences. Dans la fonction la plus simple, nous mappons simplement les positions des arguments et des paramètres. L'argument n ° 1 correspond au paramètre n ° 1, l'argument n ° 2 au paramètre n ° 2, etc.

 def printThese(a,b,c):   print(a, "is stored in a")   print(b, "is stored in b")   print(c, "is stored in c") printThese(1,2,3) """ 1 is stored in a 2 is stored in b 3 is stored in c """ 

Pour appeler une fonction, les trois arguments sont requis. Si vous ignorez au moins l'un d'entre eux, un message d'erreur s'affiche.

 def printThese(a,b,c):   print(a, "is stored in a")   print(b, "is stored in b")   print(c, "is stored in c") printThese(1,2) """ TypeError: printThese() missing 1 required positional argument: 'c' """ 

Si vous affectez une valeur par défaut au paramètre lors de la déclaration d'une fonction, il n'est plus nécessaire d'indiquer l'argument correspondant lors de l'appel de la fonction. Le paramètre devient facultatif.

 def printThese(a,b,c=None):   print(a, "is stored in a")   print(b, "is stored in b")   print(c, "is stored in c") printThese(1,2) """ 1 is stored in a 2 is stored in b None is stored in c """ 

Des paramètres facultatifs peuvent également être définis lors de l'appel d'une fonction en utilisant leurs noms.

Dans l'exemple suivant, nous allons définir les trois paramètres sur la valeur par défaut None et voir comment ils peuvent être attribués en utilisant leurs noms et sans prêter attention à l'ordre des arguments utilisés lors de l'appel de la fonction.

 def printThese(a=None,b=None,c=None):   print(a, "is stored in a")   print(b, "is stored in b")   print(c, "is stored in c") printThese(c=3, a=1) """ 1 is stored in a None is stored in b 3 is stored in c """ 

Opérateur astérisque


L'opérateur * est le plus souvent associé à l'opération de multiplication chez les personnes, mais en Python, il a une autre signification.

Cet opérateur vous permet de «déballer» les objets à l'intérieur desquels certains éléments sont stockés. Voici un exemple:

 a = [1,2,3] b = [*a,4,5,6] print(b) # [1,2,3,4,5,6] 

Ici, le contenu de la liste a pris, déballé et placé sur la liste b .

Comment utiliser * args et ** kwargs


Ainsi, nous savons que l'opérateur "astérisque" en Python est capable de "retirer" leurs éléments constitutifs des objets. Nous savons également qu'il existe deux types de fonctions paramètres. Il est possible que vous y ayez déjà pensé vous-même, mais au cas où, je dirais ceci. A savoir, *args est l'abréviation de «arguments» (arguments) et ** kwargs est l'abréviation de «mot-clé arguments» (arguments nommés).

Chacune de ces constructions est utilisée pour décompresser des arguments du type correspondant, vous permettant d'appeler des fonctions avec une liste d'arguments de longueur variable. Par exemple - créez une fonction qui peut afficher les résultats saisis par un élève dans un test:

 def printScores(student, *scores):   print(f"Student Name: {student}")   for score in scores:      print(score) printScores("Jonathan",100, 95, 88, 92, 99) """ Student Name: Jonathan 100 95 88 92 99 """ 

Je n'ai pas utilisé la construction *args lors de la déclaration d'une fonction. Au lieu de cela, j'ai *scores . Y a-t-il une erreur ici? Il n'y a pas d'erreur ici. Le fait est que «args» n'est qu'un ensemble de caractères qui sont utilisés pour désigner des arguments. La chose la plus importante ici est l'opérateur * . Et ce qui vient exactement après ne joue pas un rôle spécial. En utilisant * nous avons créé une liste d'arguments positionnels basés sur ce qui a été transmis à la fonction lors de son appel.

Après avoir compris *args , il ne devrait plus y avoir de problèmes avec la compréhension de **kwargs . Le nom, encore une fois, n'a pas d'importance. L'essentiel est deux caractères ** . Grâce à eux, un dictionnaire est créé qui contient des arguments nommés passés à la fonction lors de son appel.

 def printPetNames(owner, **pets):   print(f"Owner Name: {owner}")   for pet,name in pets.items():      print(f"{pet}: {name}") printPetNames("Jonathan", dog="Brock", fish=["Larry", "Curly", "Moe"], turtle="Shelldon") """ Owner Name: Jonathan dog: Brock fish: ['Larry', 'Curly', 'Moe'] turtle: Shelldon """ 

Résumé


Voici quelques conseils pour vous aider à éviter les problèmes courants qui surviennent lorsque vous travaillez avec des fonctions et à approfondir vos connaissances:

  • Utilisez les constructions communes *args et **kwargs pour capturer les arguments positionnels et nommés.
  • **kwarg ne peut pas être placé avant *args . Si vous procédez ainsi, un message d'erreur s'affiche.
  • Méfiez-vous des conflits entre les paramètres nommés et **kwargs , dans les cas où il est prévu de passer la valeur en tant **kwarg , mais le nom de clé de cette valeur correspond au nom du paramètre nommé.
  • L'opérateur * peut être utilisé non seulement dans les déclarations de fonction, mais également lors de leur appel.

Chers lecteurs! Quels paramètres utilisez-vous le plus souvent lors de la déclaration de fonctions Python?

Source: https://habr.com/ru/post/fr482464/


All Articles