Dans les définitions de méthode suivantes, à quoi servent les *
et **
quoi faire param2
?
def foo(param1, *param2):
def bar(param1, **param2):
Dans les définitions de méthode suivantes, à quoi servent les *
et **
quoi faire param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Pour une question demandant ce que cela signifie dans les appels de fonction (func(*[1,2])
), voir ici . Pour une question demandant comment décompresser les listes d'arguments, voir ici . Pour une question demandant ce que*
signifient les littéraux ([*[1, 2]]
), voir ici .Réponses:
Le
*args
et**kwargs
est un idiome commun pour permettre un nombre arbitraire d'arguments aux fonctions comme décrit dans la section plus sur la définition des fonctions dans la documentation Python.Le
*args
vous donnera tous les paramètres de fonction sous forme de tuple :Le
**kwargs
vous donnera tous les arguments de mot-clé, à l' exception de ceux correspondant à un paramètre formel en tant que dictionnaire.Les deux idiomes peuvent être mélangés avec des arguments normaux pour autoriser un ensemble d'arguments fixes et certains arguments variables:
Il est également possible de l'utiliser dans l'autre sens:
Une autre utilisation de l'
*l
idiome est de décompresser les listes d'arguments lors de l'appel d'une fonction.En Python 3, il est possible d'utiliser
*l
sur le côté gauche d'une affectation ( Extended Iterable Unpacking ), bien qu'il donne une liste au lieu d'un tuple dans ce contexte:Python 3 ajoute également une nouvelle sémantique (voir PEP 3102 ):
Cette fonction n'accepte que 3 arguments positionnels, et tout ce qui suit
*
ne peut être passé que comme arguments de mots clés.la source
**kwargs
maintenant correspond à l'ordre dans lequel les arguments des mots clés ont été passés à la fonction." - docs.python.org/3/whatsnew/3.6.html En fait, tous les dicts dans CPython 3.6 se souviendront de l'ordre d'insertion comme détail d'implémentation, cela devient standard dans Python 3.7.got an unexpected keyword argument 'name'
Il convient également de noter que vous pouvez également utiliser
*
et**
lorsque vous appelez des fonctions. Il s'agit d'un raccourci qui vous permet de passer plusieurs arguments à une fonction directement à l'aide d'une liste / tuple ou d'un dictionnaire. Par exemple, si vous avez la fonction suivante:Vous pouvez faire des choses comme:
Remarque: Les clés
mydict
doivent être nommées exactement comme les paramètres de fonctionfoo
. Sinon, il lancera unTypeError
:la source
Le simple * signifie qu'il peut y avoir n'importe quel nombre d'arguments positionnels supplémentaires.
foo()
peut être invoqué commefoo(1,2,3,4,5)
. Dans le corps de foo () param2 se trouve une séquence contenant 2-5.Le double ** signifie qu'il peut y avoir n'importe quel nombre de paramètres nommés supplémentaires.
bar()
peut être invoqué commebar(1, a=2, b=3)
. Dans le corps de bar () param2 se trouve un dictionnaire contenant {'a': 2, 'b': 3}Avec le code suivant:
la sortie est
la source
foobar(param1, *param2, **param3)
est nécessaire pour que cette réponse soit complète.Ils permettent aux fonctions à définir d'accepter et aux utilisateurs de passer n'importe quel nombre d'arguments, positional (
*
) et keyword (**
).Définition des fonctions
*args
permet un nombre illimité d'arguments positionnels (paramètres), qui seront attribués à un tuple nomméargs
.**kwargs
permet un nombre illimité d'arguments de mot-clé facultatifs (paramètres), qui seront dans un dict nommékwargs
.Vous pouvez (et devez) choisir n'importe quel nom approprié, mais si l'intention est que les arguments soient de sémantique non spécifique
args
etkwargs
soient des noms standard.Expansion, passage d'un nombre quelconque d'arguments
Vous pouvez également utiliser
*args
et**kwargs
pour passer des paramètres à partir de listes (ou tout itérable) et de dict (ou de tout mappage), respectivement.La fonction recevant les paramètres n'a pas besoin de savoir qu'ils sont développés.
Par exemple, xrange de Python 2 ne s'attend pas explicitement
*args
, mais puisqu'il prend 3 entiers comme arguments:Comme autre exemple, nous pouvons utiliser l'expansion de dict dans
str.format
:Nouveau dans Python 3: définition de fonctions avec des arguments de mots clés uniquement
Vous pouvez avoir des arguments de mot clé uniquement après que
*args
- par exemple, ici,kwarg2
doit être donné comme argument de mot clé - et non positionnellement:Usage:
En outre,
*
peut être utilisé par lui - même pour indiquer que les arguments que mot - clé suivent, sans tenir compte des arguments de position illimitée.Ici,
kwarg2
encore une fois, doit être un argument de mot clé explicitement nommé:Et nous ne pouvons plus accepter d'arguments positionnels illimités car nous n'avons pas
*args*
:Encore une fois, plus simplement, nous devons ici
kwarg
être donnés par un nom, et non par position:Dans cet exemple, nous voyons que si nous essayons de passer
kwarg
positionnellement, nous obtenons une erreur:Nous devons explicitement passer le
kwarg
paramètre comme argument de mot clé.Démos compatibles Python 2
*args
(généralement**kwargs
appelés "star-args") et (les étoiles peuvent être impliquées en disant "kwargs", mais être explicites avec "double-star kwargs") sont des idiomes courants de Python pour utiliser la notation*
et**
. Ces noms de variables spécifiques ne sont pas requis (par exemple, vous pouvez utiliser*foos
et**bars
), mais un écart par rapport à la convention est susceptible de faire enrager vos collègues codeurs Python.Nous les utilisons généralement lorsque nous ne savons pas ce que notre fonction va recevoir ou combien d'arguments nous pouvons passer, et parfois même lorsque nommer chaque variable séparément deviendrait très compliqué et redondant (mais c'est un cas où généralement explicite est mieux qu'implicite).
Exemple 1
La fonction suivante décrit comment ils peuvent être utilisés et illustre le comportement. Notez que l'
b
argument nommé sera consommé par le deuxième argument positionnel avant:Nous pouvons vérifier l'aide en ligne pour la signature de la fonction, avec
help(foo)
, qui nous indiqueAppelons cette fonction avec
foo(1, 2, 3, 4, e=5, f=6, g=7)
qui imprime:
Exemple 2
Nous pouvons également l'appeler à l'aide d'une autre fonction, dans laquelle nous fournissons simplement
a
:bar(100)
impressions:Exemple 3: utilisation pratique dans les décorateurs
OK, peut-être que nous ne voyons pas encore l'utilitaire. Imaginez donc que vous ayez plusieurs fonctions avec du code redondant avant et / ou après le code de différenciation. Les fonctions nommées suivantes ne sont que des pseudo-codes à des fins d'illustration.
Nous pouvons peut-être gérer cela différemment, mais nous pouvons certainement extraire la redondance avec un décorateur, et donc notre exemple ci-dessous montre comment
*args
et**kwargs
peut être très utile:Et maintenant, chaque fonction encapsulée peut être écrite de manière beaucoup plus succincte, comme nous avons pris en compte la redondance:
Et par affacturage notre code,
*args
et**kwargs
nous permet de faire, nous réduisons les lignes de code, d' améliorer la lisibilité et la maintenabilité, et sont seuls endroits canoniques pour la logique de notre programme. Si nous devons changer une partie de cette structure, nous avons un endroit où effectuer chaque changement.la source
Comprenons d'abord ce que sont les arguments positionnels et les arguments de mots clés. Voici un exemple de définition de fonction avec des arguments positionnels.
Il s'agit donc d'une définition de fonction avec des arguments positionnels. Vous pouvez également l'appeler avec un mot clé / des arguments nommés:
Étudions maintenant un exemple de définition de fonction avec des arguments de mots clés :
Vous pouvez également appeler cette fonction avec des arguments positionnels:
Nous connaissons donc maintenant les définitions de fonctions avec des arguments de position et de mot-clé.
Étudions maintenant l'opérateur '*' et l'opérateur '**'.
Veuillez noter que ces opérateurs peuvent être utilisés dans 2 domaines:
a) appel de fonction
b) définition de la fonction
L'utilisation de l'opérateur '*' et de l'opérateur '**' dans l'appel de fonction.
Passons directement à un exemple, puis discutons-en.
Alors souviens-toi
lorsque l'opérateur '*' ou '**' est utilisé dans un appel de fonction -
L'opérateur '*' décompresse la structure de données telle qu'une liste ou un tuple en arguments nécessaires à la définition de la fonction.
L'opérateur '**' décompresse un dictionnaire en arguments nécessaires à la définition de la fonction.
Étudions maintenant l'utilisation de l'opérateur '*' dans la définition de la fonction . Exemple:
Dans la définition de fonction, l'opérateur '*' regroupe les arguments reçus dans un tuple.
Voyons maintenant un exemple de '**' utilisé dans la définition de fonction:
Dans la définition de fonction L'opérateur '**' regroupe les arguments reçus dans un dictionnaire.
Alors souviens-toi:
Dans une fonction, la structure de données '*' décompresse le tuple ou la liste en arguments de position ou de mot clé à recevoir par définition de fonction.
Dans une fonction, appelez la structure de données du dictionnaire «**» pour décomposer les arguments positionnels ou mot-clé à recevoir par définition de fonction.
Dans une définition de fonction, le '*' regroupe les arguments positionnels dans un tuple.
Dans une définition de fonction, le '**' regroupe les arguments des mots clés dans un dictionnaire.
la source
Ce tableau est pratique pour utiliser
*
et**
dans la construction de fonction et l' appel de fonction :Cela ne fait que résumer la réponse de Lorin Hochstein, mais je la trouve utile.
En relation: les utilisations des opérateurs étoile / splat ont été étendues dans Python 3
la source
*
et**
ont un usage spécial dans la liste des arguments de fonction.*
implique que l'argument est une liste et**
implique que l'argument est un dictionnaire. Cela permet aux fonctions de prendre un nombre arbitraire d'argumentsla source
Pour ceux d'entre vous qui apprennent par des exemples!
*
est de vous donner la possibilité de définir une fonction qui peut prendre un nombre arbitraire d'arguments fournis sous forme de liste (par ex.f(*myList)
).**
est de vous donner la possibilité de nourrir les arguments d'une fonction en fournissant un dictionnaire (par exemplef(**{'x' : 1, 'y' : 2})
).Montrons en définissant une fonction qui prend deux variables normales
x
,y
et peut accepter plus d' arguments quemyArgs
, et peut accepter encore plus d' arguments quemyKW
. Plus tard, nous montrerons comment nourrir eny
utilisantmyArgDict
.Avertissements
**
est exclusivement réservé aux dictionnaires.**
doit venir après*
, toujours.la source
De la documentation Python:
la source
*
signifie recevoir des arguments variables sous forme de tuple**
signifie recevoir des arguments variables sous forme de dictionnaireUtilisé comme suit:
1) célibataire *
Production:
2) Maintenant
**
Production:
la source
Je veux donner un exemple que d'autres n'ont pas mentionné
* peut également déballer un générateur
Un exemple du document Python3
unzip_x sera [1, 2, 3], unzip_y sera [4, 5, 6]
Le zip () reçoit plusieurs arguments iretable et renvoie un générateur.
la source
En Python 3.5, vous pouvez également utiliser cette syntaxe
list
,dict
,tuple
etset
affiche (parfois appelés littéraux). Voir PEP 488: Généralisations de déballage supplémentaires .Il permet également de décompresser plusieurs itérables en un seul appel de fonction.
(Merci à mgilson pour le lien PEP.)
la source
En plus des appels de fonction, * args et ** kwargs sont utiles dans les hiérarchies de classes et évitent également d'avoir à écrire la
__init__
méthode en Python. Une utilisation similaire peut être vue dans des frameworks comme le code Django.Par exemple,
Une sous-classe peut alors être
La sous-classe doit ensuite être instanciée comme
En outre, une sous-classe avec un nouvel attribut qui n'a de sens que pour cette instance de sous-classe peut appeler la classe Base
__init__
pour décharger le paramètre d'attributs. Cela se fait via * args et ** kwargs. kwargs est principalement utilisé pour que le code soit lisible à l'aide d'arguments nommés. Par exemple,qui peut être créé comme
Le code complet est ici
la source
S'appuyant sur la réponse de Nickd ...
Production:
Fondamentalement, n'importe quel nombre d' arguments positionnels peut utiliser * args et tous les arguments nommés (ou kwargs aka arguments de mots clés) peuvent utiliser ** kwargs.
la source
*args
et**kwargs
: vous permettent de passer un nombre variable d'arguments à une fonction.*args
: est utilisé pour envoyer une liste d'arguments de longueur variable non mot-clé à la fonction:Produira:
**kwargs*
**kwargs
vous permet de passer une longueur variable d'arguments mot-clé à une fonction. Vous devez utiliser**kwargs
si vous souhaitez gérer des arguments nommés dans une fonction.Produira:
la source
Cet exemple vous aiderait à vous souvenir
*args
,**kwargs
et même à l'super
héritage en Python à la fois.la source
Un bon exemple d'utilisation des deux dans une fonction est:
la source
TL; DR
Voici 6 cas d'utilisation différents pour
*
et**
dans la programmation python:*args
:def foo(*args): pass
, icifoo
accepte un certain nombre d'arguments de position, à savoir, les appels suivants sont validesfoo(1)
,foo(1, 'bar')
**kwargs
:def foo(**kwargs): pass
, ici « foo » accepte un certain nombre d'arguments mot - clé, à savoir, les appels suivants sont validesfoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:def foo(*args, **kwargs): pass
, icifoo
accepte un certain nombre d'arguments de position et de mots - clés, à savoir les appels suivants sont validesfoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:def foo(pos1, pos2, *, kwarg1): pass
, ici*
signifie que foo accepte uniquement les arguments clés après pos2, par conséquentfoo(1, 2, 3)
soulève TypeError maisfoo(1, 2, kwarg1=3)
est ok.*_
(Remarque: ceci est une convention uniquement):def foo(bar, baz, *_): pass
signifie (par convention)foo
n'utilise que des argumentsbar
etbaz
dans son fonctionnement et ignorera les autres.\**_
(Remarque: ceci est une convention uniquement):def foo(bar, baz, **_): pass
signifie (par convention)foo
n'utilise que des argumentsbar
etbaz
dans son fonctionnement et ignorera les autres.BONUS: à partir de python 3.8, on peut utiliser
/
dans la définition de fonction pour appliquer des paramètres positionnels uniquement. Dans l'exemple suivant, les paramètres a et b sont uniquement positionnels , tandis que c ou d peut être positionnel ou mot-clé, et e ou f doivent être des mots-clés:la source
TL; DR
Il regroupe les arguments passés à la fonction dans
list
etdict
respectivement à l'intérieur du corps de la fonction. Lorsque vous définissez une signature de fonction comme celle-ci:il peut être appelé avec n'importe quel nombre d'arguments et d'arguments de mots clés. Les arguments non mot-clés sont regroupés dans une liste appelée
args
à l'intérieur du corps de la fonction et les arguments mot-clés sont regroupés dans un dict appelékwds
à l'intérieur du corps de la fonction.maintenant à l'intérieur du corps de la fonction, lorsque la fonction est appelée, il y a deux variables locales,
args
qui est une liste ayant une valeur["this", "is a list of", "non-keyword", "arguments"]
etkwds
qui est unedict
valeur ayant{"keyword" : "ligma", "options" : [1,2,3]}
Cela fonctionne également en sens inverse, c'est-à-dire du côté de l'appelant. par exemple si vous avez une fonction définie comme:
vous pouvez l'appeler avec en déballant les itérables ou les mappages que vous avez dans la portée d'appel:
la source
Le contexte
**
Utiliser avec la mise en forme des chaînes
En plus des réponses dans ce fil, voici un autre détail qui n'a pas été mentionné ailleurs. Cela élargit la réponse de Brad Solomon
Le décompactage avec
**
est également utile lors de l'utilisation de pythonstr.format
.Ceci est quelque peu similaire à ce que vous pouvez faire avec la
f-strings
chaîne f de python mais avec la surcharge supplémentaire de déclaration d'un dict pour contenir les variables (la chaîne f ne nécessite pas de dict).Exemple rapide
la source
def foo(param1, *param2):
est une méthode qui peut accepter un nombre arbitraire de valeurs pour*param2
,def bar(param1, **param2):
est une méthode qui peut accepter un nombre arbitraire de valeurs avec des clés pour*param2
param1
est un paramètre simple.Par exemple, la syntaxe pour implémenter varargs en Java comme suit:
la source