Comprendre kwargs en Python
 à quoi sert **kwargs  en Python?  
 je sais que vous pouvez faire un objects.filter sur une table et passer dans un argument **kwargs .    
 puis-je également le faire pour spécifier des deltas de temps comme timedelta(hours = time1) ?   
  comment ça marche exactement? Est-ce que c'est classe comme "déballage"? Comme  a,b=1,2 ?  
10 réponses
  vous pouvez utiliser  **kwargs  pour laisser vos fonctions prendre un nombre arbitraire d'arguments de mots clés ("kwargs" signifie "arguments de mots clés"):  
>>> def print_keyword_args(**kwargs):
...     # kwargs is a dict of the keyword args passed to the function
...     for key, value in kwargs.iteritems():
...         print "%s = %s" % (key, value)
... 
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe
  
    vous pouvez également utiliser la syntaxe  **kwargs  lorsque vous appelez des fonctions en construisant un dictionnaire d'arguments de mots clés et en le passant à votre fonction:  
>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith
  
  le tutoriel Python contient une bonne explication de la façon dont il fonctionne, avec quelques nice exemple.
< --Update-->
pour les personnes utilisant Python 3, au lieu de iteritems (), utilisez items ()
dictionnaires de déballage
  **  dictionnaires non emballés.  
Ce
func(a=1, b=2, c=3)
  
  est le même que
args = {'a': 1, 'b': 2, 'c':3}
func(**args)
  
  il est utile si vous devez construire des paramètres:
args = {'name': person.name}
if hasattr(person, "address"):
    args["address"] = person.address
func(**args)  # either expanded to func(name=person.name) or
              #                    func(name=person.name, address=person.address)
  
  paramètres D'emballage d'une fonction
def setstyle(**styles):
    for key, value in styles.iteritems():      # styles is a regular dictionary
        setattr(someobject, key, value)
  
  Cela vous permet d'utiliser la fonction comme ceci:
setstyle(color="red", bold=False)
  
    	                kwargs est juste un dictionnaire qui est ajouté aux paramètres.
un dictionnaire peut contenir des couples de clés et de valeurs. Et ce sont les kwargs. Ok, c'est de cette façon.
le whatfor n'est pas si simple.
par exemple (très hypothétique) vous avez une interface qui appelle simplement d'autres routines pour faire le travail:
def myDo(what, where, why):
   if what == 'swim':
      doSwim(where, why)
   elif what == 'walk':
      doWalk(where, why)
   ...
  
  Maintenant vous obtenez une nouvelle méthode "drive":
elif what == 'drive':
   doDrive(where, why, vehicle)
  
  mais attendez une minute, il y a un nouveau paramètre "véhicule" -- vous ne le connaissiez pas avant. Maintenant, vous devez l'ajouter à la signature de la myDo-fonction.
ici vous pouvez lancer kwargs dans le jeu -- vous ajoutez juste kwargs à la signature:
def myDo(what, where, why, **kwargs):
   if what == 'drive':
      doDrive(where, why, **kwargs)
   elif what == 'swim':
      doSwim(where, why, **kwargs)
  
  de cette façon, vous n'avez pas besoin de changer la signature de votre fonction d'interface chaque fois que certaines de vos routines appelées pourraient changer.
C'est juste un bel exemple, vous pourriez trouver kwargs utile.
sur la base du fait qu'un bon échantillon est parfois meilleur qu'un long discours, j'écrirai deux fonctions en utilisant toutes les facilités de passage d'arguments variables python (à la fois des arguments de position et des arguments nommés). Vous devriez facilement être en mesure de voir ce qu'il fait par vous-même:
def f(a = 0, *args, **kwargs):
    print("Received by f(a, *args, **kwargs)")
    print("=> f(a=%s, args=%s, kwargs=%s" % (a, args, kwargs))
    print("Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)")
    g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
def g(f, g = 0, *args, **kwargs):
    print("Received by g(f, g = 0, *args, **kwargs)")
    print("=> g(f=%s, g=%s, args=%s, kwargs=%s)" % (f, g, args, kwargs))
print("Calling f(1, 2, 3, 4, b = 5, c = 6)")
f(1, 2, 3, 4, b = 5, c = 6)
  
  et voici la sortie:
Calling f(1, 2, 3, 4, b = 5, c = 6)
Received by f(a, *args, **kwargs) 
=> f(a=1, args=(2, 3, 4), kwargs={'c': 6, 'b': 5}
Calling g(10, 11, 12, *args, d = 13, e = 14, **kwargs)
Received by g(f, g = 0, *args, **kwargs)
=> g(f=10, g=11, args=(12, 2, 3, 4), kwargs={'c': 6, 'b': 5, 'e': 14, 'd': 13})
  
    	                     Motif:  *args  et  **kwargs  est un espace réservé pour les arguments qui doivent être transmis à un appel de fonction     
  utilisant  *args  et  **kwargs  pour appeler une fonction  
def args_kwargs_test(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3
  
    maintenant, nous allons utiliser *args pour appeler la fonction définie ci-dessus 
#args can either be a "list" or "tuple"
>>> args = ("two", 3, 5)  
>>> args_kwargs_test(*args)
  
  résultat:
  arg1: deux  
     
arg2: 3  
     
arg3: 5  
  maintenant, en utilisant  **kwargs  pour appeler la même fonction  
#keyword argument "kwargs" has to be a dictionary
>>> kwargs = {"arg3":3, "arg2":'two', "arg1":5}
>>> args_kwargs_test(**kwargs)
  
  résultat:
  arg1: 5  
     
arg2: deux  
     
arg3: 3  
  Bottomline:  *args  n'a pas d'intelligence, il interpole simplement les args passés aux paramètres (dans l'ordre de gauche à droite) tandis que  **kwargs  se comporte intelligemment en plaçant la valeur appropriée @ l'endroit désiré  
-    
kwargsdans**kwargsest juste le nom de la variable. Vous pouvez très bien avoir**anyVariableName -    
kwargssignifie" arguments de mots clés". Mais je pense qu'ils devraient plutôt être appelés comme "arguments nommés", car ce sont simplement des arguments transmis avec des noms (Je ne trouve aucune signification au mot" mot-clé "dans le terme"arguments de mots-clés". Je suppose que "mot-clé" signifie habituellement des mots réservés par le langage de programmation et donc ne pas être utilisé par le programmeur pour Noms variables. Rien de Tel ne se produit ici en cas de kwargs.). Alors on donne des nomsparam1etparam2à deux valeurs paramétriques transmises à la fonction comme suit:func(param1="val1",param2="val2"), au lieu de passer seulement les valeurs:func(val1,val2). Ainsi, je pense qu'ils devraient être correctement appelés "nombre arbitraire d'arguments nommés" comme nous pouvons spécifier n'importe quel nombre de ces paramètres (c'est-à-dire, arguments) sifunca la signaturefunc(**kwargs) 
  ainsi dit que permettez-moi d'expliquer "arguments nommés" d'abord et puis "nombre arbitraire d'arguments nommés"  kwargs .  
les arguments Nommés
- nommé args devraient suivre de position args
 - l'ordre de named args n'est pas important
 -    
exemple
def function1(param1,param2="arg2",param3="arg3"): print("\n"+str(param1)+" "+str(param2)+" "+str(param3)+"\n") function1(1) #1 arg2 arg3 #1 positional arg function1(param1=1) #1 arg2 arg3 #1 named arg function1(1,param2=2) #1 2 arg3 #1 positional arg, 1 named arg function1(param1=1,param2=2) #1 2 arg3 #2 named args function1(param2=2, param1=1) #1 2 arg3 #2 named args out of order function1(1, param3=3, param2=2) #1 2 3 # #function1() #invalid: required argument missing #function1(param2=2,1) #invalid: SyntaxError: non-keyword arg after keyword arg #function1(1,param1=11) #invalid: TypeError: function1() got multiple values for argument 'param1' #function1(param4=4) #invalid: TypeError: function1() got an unexpected keyword argument 'param4' 
     nombre Arbitraire d'arguments nommés  kwargs      
-   séquence des paramètres de fonction:
  
- paramètres de position
 - paramètre formel de la capture nombre arbitraire d'arguments (avec le préfixe *)
 - nommé paramètres formels
 - paramètre formel capturant le nombre arbitraire de paramètres nommés (préfixé par**)
 
 -    
exemple
def function2(param1, *tupleParams, param2, param3, **dictionaryParams): print("param1: "+ param1) print("param2: "+ param2) print("param3: "+ param3) print("custom tuple params","-"*10) for p in tupleParams: print(str(p) + ",") print("custom named params","-"*10) for k,v in dictionaryParams.items(): print(str(k)+":"+str(v)) function2("arg1", "custom param1", "custom param2", "custom param3", param3="arg3", param2="arg2", customNamedParam1 = "val1", customNamedParam2 = "val2" ) # Output # #param1: arg1 #param2: arg2 #param3: arg3 #custom tuple params ---------- #custom param1, #custom param2, #custom param3, #custom named params ---------- #customNamedParam2:val2 #customNamedParam1:val1 
passer tuple et dict variables for custom args
pour finir, laissez-moi aussi noter que nous pouvons passer
- "paramètre formel capturant le nombre arbitraire d'arguments" comme tuple variable et
 - " paramètre formel capturant le nombre arbitraire de named paramètres "comme variable dict
 
ainsi, le même appel ci-dessus peut être fait comme suit:
tupleCustomArgs = ("custom param1", "custom param2", "custom param3")
dictCustomNamedArgs = {"customNamedParam1":"val1", "customNamedParam2":"val2"}
function2("arg1",
      *tupleCustomArgs,    #note *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs     #note **
      )
  
    enfin la note  *  et  **  dans les appels de fonction ci-dessus. Si nous omettons, nous pouvons obtenir de mauvais résultats.  
  Omettant  *  dans tuple args:  
function2("arg1",
      tupleCustomArgs,   #omitting *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs
      )
  
  imprime
param1: arg1
param2: arg2
param3: arg3
custom tuple params ----------
('custom param1', 'custom param2', 'custom param3'),
custom named params ----------
customNamedParam2:val2
customNamedParam1:val1
  
    au-dessus de tuple  ('custom param1', 'custom param2', 'custom param3')  est imprimé tel quel.   
  Omettant  dict  args:  
function2("arg1",
      *tupleCustomArgs,   
      param3="arg3",
      param2="arg2", 
      dictCustomNamedArgs   #omitting **
      )
  
  donne
dictCustomNamedArgs
         ^
SyntaxError: non-keyword arg after keyword arg
  
    	                en plus, vous pouvez également mélanger différents modes d'utilisation lors de l'appel de fonctions kwargs:
def test(**kwargs):
    print kwargs['a']
    print kwargs['b']
    print kwargs['c']
args = { 'b': 2, 'c': 3}
test( a=1, **args )
  
  donne cette sortie:
1
2
3
  
  notez que * * kwargs doit être le dernier argument
Voici une fonction simple qui sert à expliquer l'usage:
def print_wrap(arg1, *args, **kwargs):
    print(arg1)
    print(args)
    print(kwargs)
    print(arg1, *args, **kwargs)
  
    tout argument qui est  Non  spécifié dans la définition de la fonction sera mis dans la liste args , ou la liste kwargs , selon qu'il s'agit d'arguments de mots clés ou non:  
>>> print_wrap('one', 'two', 'three', end='blah', sep='--')
one
('two', 'three')
{'end': 'blah', 'sep': '--'}
one--two--threeblah
  
  si vous ajoutez un argument de mot-clé qui n'est jamais passé à une fonction, une erreur sera soulevée:
>>> print_wrap('blah', dead_arg='anything')
TypeError: 'dead_arg' is an invalid keyword argument for this function
  
    	                voici un exemple que j'espère utile:
#! /usr/bin/env python
#
def g( **kwargs) :
  print ( "In g ready to print kwargs" )
  print kwargs
  print ( "in g, calling f")
  f ( **kwargs )
  print ( "In g, after returning from f")
def f( **kwargs ) :
  print ( "in f, printing kwargs")
  print ( kwargs )
  print ( "In f, after printing kwargs")
g( a="red", b=5, c="Nassau")
g( q="purple", w="W", c="Charlie", d=[4, 3, 6] )
  
  quand vous exécutez le programme, vous obtenez:
$ python kwargs_demo.py 
In g ready to print kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
in g, calling f
in f, printing kwargs
{'a': 'red', 'c': 'Nassau', 'b': 5}
In f, after printing kwargs
In g, after returning from f
In g ready to print kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
in g, calling f
in f, printing kwargs
{'q': 'purple', 'c': 'Charlie', 'd': [4, 3, 6], 'w': 'W'}
In f, after printing kwargs
In g, after returning from f
  
  la clé emporte ici est que le nombre variable d'arguments nommés dans l'appel traduire dans un dictionnaire dans la fonction.