Wat is het doel en het gebruik van **kwargs?

Wat zijn de toepassingen voor **kwargs in Python?

Ik weet dat je een objects.filter op een tafel kunt doen en een **kwargs-argument kunt invoeren.  

Kan ik dit ook doen voor het specificeren van tijddelta’s, bijv. timedelta(hours = time1)?

Hoe werkt het precies? Is het klassen als ‘uitpakken’? Vind je a,b=1,2 leuk?


Antwoord 1, autoriteit 100%

U kunt **kwargs gebruiken om uw functies een willekeurig aantal trefwoordargumenten te laten aannemen (“kwargs” betekent “trefwoordargumenten”):

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

U kunt ook de syntaxis **kwargs gebruiken bij het aanroepen van functies door een woordenboek met trefwoordargumenten samen te stellen en door te geven aan uw functie:

>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith

De Python Tutorial bevat een goede uitleg over hoe het werkt, samen met enkele mooie voorbeelden.

Python 3-update

Gebruik voor Python 3 in plaats van iteritems() items()


Antwoord 2, autoriteit 40%

Woordenboeken uitpakken

** pakt woordenboeken uit.

Dit

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

is hetzelfde als

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

Het is handig als u parameters moet maken:

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)

Parameters van een functie inpakken

  • Gebruik .items() in plaats van .iteritems() voor python 3
def setstyle(**styles):
    for key, value in styles.iteritems():      # styles is a regular dictionary
        setattr(someobject, key, value)

Hiermee kunt u de functie als volgt gebruiken:

setstyle(color="red", bold=False)

Opmerkingen

  • kwargs is een variabelenaam die wordt gebruikt voor trefwoordargumenten, een andere variabelenaam kan worden gebruikt. Het belangrijkste is dat het een woordenboek is en dat het wordt uitgepakt met de dubbele asterisk-operator **.
  • Andere iterables worden uitgepakt met de enkele asterisk-operator *
  • Om verwarring te voorkomen, is het waarschijnlijk het beste om de namen van de erkende variabelen, kwargs en args, voor respectievelijk woordenboeken en andere iterables te gebruiken.

Bronnen


Antwoord 3, autoriteit 8%

kwargs is slechts een woordenboek dat aan de parameters wordt toegevoegd.

Een woordenboek kan sleutel-waardeparen bevatten. En dat zijn de kwargs. Oké, dit is hoe.

Het waarvoor is niet zo eenvoudig.

Bijvoorbeeld (zeer hypothetisch) je hebt een interface die gewoon andere routines aanroept om het werk te doen:

def myDo(what, where, why):
   if what == 'swim':
      doSwim(where, why)
   elif what == 'walk':
      doWalk(where, why)
   ...

Nu krijg je een nieuwe methode “drive”:

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

Maar wacht even, er is een nieuwe parameter “voertuig” — je wist het niet eerder. Nu moet je het toevoegen aan de handtekening van de myDo-functie.

Hier kun je kwargs in het spel gooien — je voegt gewoon kwargs toe aan de handtekening:

def myDo(what, where, why, **kwargs):
   if what == 'drive':
      doDrive(where, why, **kwargs)
   elif what == 'swim':
      doSwim(where, why, **kwargs)

Op deze manier hoeft u de handtekening van uw interfacefunctie niet elke keer te wijzigen als sommige van uw aangeroepen routines veranderen.

Dit is slechts een mooi voorbeeld waar kwargs nuttig voor zou kunnen zijn.


Antwoord 4, autoriteit 5%

Op basis van het feit dat een goede steekproef soms beter is dan een lange verhandeling, zal ik twee functies schrijven met gebruikmaking van alle python-variabele argument-passing-faciliteiten (zowel positionele als benoemde argumenten). Je zou gemakkelijk zelf moeten kunnen zien wat het doet:

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)

En hier is de uitvoer:

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

Antwoord 5, autoriteit 3%

Motief: *args en **kwargs dienen als tijdelijke aanduiding voor de argumenten die moeten worden doorgegeven aan een functieaanroep

gebruik *args en **kwargs om een ​​functie aan te roepen

def args_kwargs_test(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

Nu gebruiken we *args om de hierboven gedefinieerde functie aan te roepen

#args can either be a "list" or "tuple"
>>> args = ("two", 3, 5)  
>>> args_kwargs_test(*args)

resultaat:

arg1: twee
arg2: 3
arg3: 5


Gebruik nu **kwargs om dezelfde functie aan te roepen

#keyword argument "kwargs" has to be a dictionary
>>> kwargs = {"arg3":3, "arg2":'two', "arg1":5}
>>> args_kwargs_test(**kwargs)

resultaat:

arg1: 5
arg2: twee
arg3: 3

Bottomline: *args heeft geen intelligentie, het interpoleert eenvoudig de doorgegeven argumenten naar de parameters (in de volgorde van links naar rechts), terwijl **kwargs zich intelligent gedraagt ​​door het plaatsen van de juiste waarde @ de gewenste plaats


Antwoord 6, autoriteit 3%

  • kwargs in **kwargs is gewoon een variabelenaam. Je kunt heel goed **anyVariableName
  • . hebben

  • kwargs staat voor “zoekwoordargumenten”. Maar ik vind dat ze beter moeten worden genoemd als “benoemde argumenten”, omdat dit gewoon argumenten zijn die samen met namen worden doorgegeven (ik vind geen betekenis aan het woord “trefwoord” in de term “zoekwoordargumenten”. Ik denk dat “trefwoord” meestal betekent woorden die zijn gereserveerd door de programmeertaal en dus niet door de programmeur mogen worden gebruikt voor variabelenamen. Zoiets gebeurt hier niet in het geval van kwargs.). Dus we geven namen
    param1 en param2 tot twee parameterwaarden die als volgt aan de functie worden doorgegeven: func(param1="val1",param2="val2"), in plaats van alleen waarden door te geven: func(val1,val2). Daarom vind ik dat ze op de juiste manier “willekeurig aantal benoemde argumenten” moeten worden genoemd, omdat we een willekeurig aantal van deze parameters (dat wil zeggen argumenten) kunnen specificeren als func handtekening heeft func(**kwargs)

Dat gezegd hebbende, laat me eerst “benoemde argumenten” uitleggen en daarna “willekeurig aantal benoemde argumenten” kwargs.

Benoemde argumenten

  • benoemde args moeten positionele args volgen
  • volgorde van benoemde argumenten is niet belangrijk
  • Voorbeeld

    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'
    

Willekeurig aantal benoemde argumenten kwargs

  • Opeenvolging van functieparameters:
    1. positionele parameters
    2. formele parameter die een willekeurig aantal argumenten vastlegt (voorafgegaan door *)
    3. formele parameters genoemd
    4. formele parameter die een willekeurig aantal benoemde parameters vastlegt (voorafgegaan door **)
  • Voorbeeld

    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
    

Tuple- en dict-variabelen doorgeven voor aangepaste argumenten

Om het af te maken, wil ik ook opmerken dat we kunnen slagen

  • “formele parameter die een willekeurig aantal argumenten vastlegt” als tuple-variabele en
  • “formele parameter die een willekeurig aantal benoemde parameters vastlegt” als dict-variabele

Dus hetzelfde bovenstaande gesprek kan als volgt worden gedaan:

tupleCustomArgs = ("custom param1", "custom param2", "custom param3")
dictCustomNamedArgs = {"customNamedParam1":"val1", "customNamedParam2":"val2"}
function2("arg1",
      *tupleCustomArgs,    #note *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs     #note **
      )

Ten slotte nog * en ** in bovenstaande functie-aanroepen. Als we ze weglaten, kunnen we slechte resultaten krijgen.

* weglaten in tuple-args:

function2("arg1",
      tupleCustomArgs,   #omitting *
      param3="arg3",
      param2="arg2", 
      **dictCustomNamedArgs
      )

afdrukken

param1: arg1
param2: arg2
param3: arg3
custom tuple params ----------
('custom param1', 'custom param2', 'custom param3'),
custom named params ----------
customNamedParam2:val2
customNamedParam1:val1

Boven tuple ('custom param1', 'custom param2', 'custom param3') wordt afgedrukt zoals het is.

Args dict weglaten:

function2("arg1",
      *tupleCustomArgs,   
      param3="arg3",
      param2="arg2", 
      dictCustomNamedArgs   #omitting **
      )

geeft

dictCustomNamedArgs
         ^
SyntaxError: non-keyword arg after keyword arg

Antwoord 7

Als toevoeging kunt u ook verschillende manieren van gebruik combineren bij het aanroepen van kwargs-functies:

def test(**kwargs):
    print kwargs['a']
    print kwargs['b']
    print kwargs['c']
args = { 'b': 2, 'c': 3}
test( a=1, **args )

geeft deze output:

1
2
3

Merk op dat **kwargs het laatste argument moet zijn


Antwoord 8

Hier is een eenvoudige functie die dient om het gebruik uit te leggen:

def print_wrap(arg1, *args, **kwargs):
    print(arg1)
    print(args)
    print(kwargs)
    print(arg1, *args, **kwargs)

Alle argumenten die niet zijn opgegeven in de functiedefinitie, worden in de lijst args of in de lijst kwargs geplaatst, afhankelijk van of het zijn zoekwoordargumenten of niet:

>>> print_wrap('one', 'two', 'three', end='blah', sep='--')
one
('two', 'three')
{'end': 'blah', 'sep': '--'}
one--two--threeblah

Als u een trefwoordargument toevoegt dat nooit aan een functie wordt doorgegeven, wordt een fout weergegeven:

>>> print_wrap('blah', dead_arg='anything')
TypeError: 'dead_arg' is an invalid keyword argument for this function

Antwoord 9

kwargs zijn een syntactische suiker om naamargumenten door te geven als woordenboeken (for func), of woordenboeken als benoemde argumenten (to func)


Antwoord 10

Hier is een voorbeeld waarvan ik hoop dat het nuttig is:

#! /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] )

Als je het programma uitvoert, krijg je:

$ 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

Het belangrijkste is dat het variabele aantal benoemde argumenten in de aanroep zich vertaalt in een woordenboek in de functie.


Antwoord 11

Trefwoordargumenten worden in Python vaak afgekort tot kwargs. In computerprogrammering,

zoekwoordargumenten verwijzen naar de ondersteuning van een computertaal voor functie
aanroepen die duidelijk de naam van elke parameter binnen de . vermelden
functie-aanroep.

Het gebruik van de twee asterisken voor de parameternaam, **kwargs, is wanneer men niet weet hoeveel sleutelwoordargumenten aan de functie zullen worden doorgegeven. Wanneer dat het geval is, worden dit Arbitrary / Wildcard Keyword Argumenten genoemd.

Een voorbeeld hiervan zijn Django’s ontvangerfuncties .

def my_callback(sender, **kwargs):
    print("Request finished!")

Merk op dat de functie een afzenderargument nodig heeft, samen met een jokerteken
trefwoordargumenten (**kwargs); alle signaalbehandelaars moeten deze nemen
argumenten.
Alle signalen sturen trefwoordargumenten en kunnen deze veranderen
zoekwoordargumenten op elk moment. In het geval van request_finished, s
gedocumenteerd als het verzenden van geen argumenten, wat betekent dat we in de verleiding kunnen komen om
schrijf onze signaalverwerking als my_callback(sender).

Dit zou verkeerd zijn – in feite zal Django een foutmelding geven als je dat doet
dus. Dat komt omdat er op elk moment argumenten kunnen worden toegevoegd aan de
signaal en je ontvanger moet die nieuwe argumenten aankunnen.

Merk op dat het niet kwargs hoeft te heten, maar het moet ** hebben (de naam kwargs is een conventie).


Antwoord 12

Dit is het eenvoudige voorbeeld om te begrijpen over python uitpakken,

>>> def f(*args, **kwargs):
...    print 'args', args, 'kwargs', kwargs

eg1:

>>>f(1, 2)
>>> args (1,2) kwargs {} #args return parameter without reference as a tuple
>>>f(a = 1, b = 2)
>>> args () kwargs {'a': 1, 'b': 2} #args is empty tuple and kwargs return parameter with reference as a dictionary

Antwoord 13

In Java gebruik je constructors om klassen te overbelasten en meerdere invoerparameters toe te staan. In python kun je kwargs gebruiken om soortgelijk gedrag te vertonen.

java-voorbeeld: https://beginnersbook.com/2013/05/constructor-overloading /

python-voorbeeld:

class Robot():
    # name is an arg and color is a kwarg
    def __init__(self,name, color='red'):
        self.name = name
        self.color = color
red_robot = Robot('Bob')
blue_robot = Robot('Bob', color='blue')
print("I am a {color} robot named {name}.".format(color=red_robot.color, name=red_robot.name))
print("I am a {color} robot named {name}.".format(color=blue_robot.color, name=blue_robot.name))
>>> I am a red robot named Bob.
>>> I am a blue robot named Bob.

gewoon een andere manier om erover na te denken.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes