851 votes

La compréhension kwargs en Python

Quels sont les usages de **kwargs en Python?

Je sais que vous pouvez faire une objects.filter sur une table et passer dans un **kwargs argument.

Je peux aussi le faire pour la spécification de temps deltas c'est à dire timedelta(hours = time1)?

Exactement comment ça marche? Est-il des classes comme les "décortiquer"? Comme a,b=1,2?

952voto

Pär Wieslander Points 11258

Vous pouvez utiliser **kwargs laisser votre prise de fonctions d'un nombre arbitraire d'arguments mots-clefs:

>>> 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 l' **kwargs de syntaxe lors de l'appel de fonctions par la construction d'un dictionnaire de mot-clé arguments et de les transmettre à 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 beaux exemples.

384voto

Georg Schölly Points 63123

Déballage des dictionnaires

** ne déballez les dictionnaires.

Cette

func(a=1, b=2, c=3)

est le même que

args = {'a': 1, 'b': 2, 'c':3}
func(**args)

C'est utile si vous avez à 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)

Emballage paramètres 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)

74voto

Juergen Points 4839

kwargs est juste un dictionnaire qui est ajouté aux paramètres.

Un dictionnaire peut contenir des clés, des paires de valeurs. Et qui sont les kwargs. Ok, c'est de cette façon.

Les whatfor n'est pas si simple.

Par exemple (très hypothétique) vous disposez d'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 de "drive":

elif what == 'drive':
   doDrive(where, why, vehicle)

Mais attendez une minute, il y a un nouveau paramètre "véhicule" -- vous n'avez pas le savoir avant. Maintenant, vous devez l'ajouter à la signature de la myDo-fonction.

Ici, vous pouvez jeter kwargs en jeu:

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 modifier la signature de votre interface de la fonction à chaque fois qu'un de vos appelée routines sont susceptibles de changer.

C'est juste une belle exemple, vous pouvez trouver kwargs utile.

57voto

kriss Points 10450

Sur la base qu'un bon exemple vaut parfois mieux qu'un long discours, je vais écrire deux fonctions à l'aide de toutes les variable python argument en passant installations (à la fois la position et les arguments nommés). Vous devriez être facilement en mesure de voir ce qu'il fait par vous-même:

def f(a = 0, *args, **kwargs):
    print("Received by fn(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 fn(1, 2, 3, 4, b = 5, c = 6)")
f(1, 2, 3, 4, b = 5, c = 6)

Et voici le résultat:

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})

34voto

mario23 Points 322

à l'aide de *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 d'appeler la fonction définie ci-dessus

>>> args = ("two", 3, 5)
>>> args_kwargs_test(*args)

résultat

arg1: deux
arg2: 3
arg3: 5

Maintenant, à l'aide de **kwargs d'appeler la même fonction

>>> 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 suffit d'interpoler le passé args tout **kwargs se comporte intelligemment en plaçant la valeur appropriée @ l'endroit désiré

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X