Naudojant * args ir ** kwargs

Todėl man sunku su *args ir **kwargs .

Iki šiol sužinojau, kad:

  • *args = argumentų sąrašas - kaip vietiniai argumentai
  • **kwargs = žodynas - kurių raktai tampa atskirais raktinio žodžio argumentais, o reikšmės tampa šių argumentų reikšmėmis.

Aš nesuprantu, kokia programavimo užduotis tai būtų naudinga.

Gali būti:

Manau, kad įvesti sąrašus ir žodynus kaip funkcijų argumentus Ir tuo pačiu metu, kaip ir pakaitos simbolis, galiu perduoti bet kokį argumentą?

Ar yra paprastas pavyzdys, kaip paaiškinti, kaip naudojami *args ir **kwargs ?

Taip pat pamokoje, kurią radau, buvo naudojamas tik „*“ ir kintamojo pavadinimas.

Ar *args ir **kwargs tik vietiniai lankytojai arba kodą naudojate tiksliai *args ir **kwargs ?

1242
03 авг. nustatė MacPython 03 rugpjūtis 2010-08-03 11:28 '10, 11:28, 2010-08-03 11:28
@ 11 atsakymų

Sintaksė yra * ir ** . Pavadinimai *args ir **kwargs yra tik sąlyginiai, tačiau nėra griežto reikalavimo juos naudoti.

Galite naudoti *args kai nežinote, kiek argumentų galima perduoti jūsų funkcijai, t.y. leidžia jums perduoti savo funkcijai savavališką skaičių argumentų. Pavyzdžiui:

 >>> def print_everything(*args): for count, thing in enumerate(args): ... print( '{0}. {1}'.format(count, thing)) ... >>> print_everything('apple', 'banana', 'cabbage') 0. apple 1. banana 2. cabbage 

Panašiai, **kwargs leidžia apdoroti anksčiau nurodytus argumentus:

 >>> def table_things(**kwargs): ... for name, value in kwargs.items(): ... print( '{0} = {1}'.format(name, value)) ... >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable apple = fruit 

Juos galite naudoti su nurodytais argumentais. Aiškūs argumentai pirmiausia gauna vertes, o tada visi kiti perduodami *args ir **kwargs . Nurodomi nurodyti argumentai. Pavyzdžiui:

 def table_things(titlestring, **kwargs) 

Taip pat galite naudoti abu parametrus tame pačiame funkcijų apibrėžime, bet *args turėtų įvykti prieš **kwargs .

Taip pat galite naudoti sintaksę * ir ** kai skambinate funkcijai. Pavyzdžiui:

 >>> def print_three_things(a, b, c): ... print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c)) ... >>> mylist = ['aardvark', 'baboon', 'cat'] >>> print_three_things(*mylist) a = aardvark, b = baboon, c = cat 

Kaip matote, šiuo atveju jis užima elementų sąrašą (arba paketą) ir ištrina jį. Šiuo atveju jis lygina juos su funkcijoje pateiktais argumentais. Žinoma, jūs galite turėti * tiek funkcijų apibrėžtyje, tiek funkcijų skambutyje.

1521
03 авг. atsakymą pateikė Dave Webb 03 rug. 2010-08-03 11:38 '10, 11:38, 2010-08-03 11:38

Viena vieta, kur naudojant *args ir **kwargs gana naudinga poklasiui.

 class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs) 

Tokiu būdu jūs galite išplėsti „Foo“ klasės elgesį nežinodami per daug apie „Foo“. Tai gali būti gana patogu, jei programuojate API, kuri gali keistis. „MyFoo“ tiesiog perduoda visus argumentus Foo klasei.

453
03 авг. Van van Lent atsakymas 03 rugpjūčio mėn. 2010-08-03 11:39 '10, 11:39, 2010-08-03 11:39

Štai pavyzdys, kuriame naudojami 3 skirtingi parametrų tipai.

 def func(required_arg, *args, **kwargs): # required_arg is a positional-only parameter. print required_arg # args is a tuple of positional arguments, # because the parameter name has * prepended. if args: # If args is not empty. print args # kwargs is a dictionary of keyword arguments, # because the parameter name has ** prepended. if kwargs: # If kwargs is not empty. print kwargs >>> func() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: func() takes at least 1 argument (0 given) >>> func("required argument") required argument >>> func("required argument", 1, 2, '3') required argument (1, 2, '3') >>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo") required argument (1, 2, '3') {'keyword2': 'foo', 'keyword1': 4} 
290
03 авг. Atsakymas pateikiamas Kit 03 rug. 2010-08-03 11:42 '10, 11:42 val. 2010-08-03 11:42

Čia yra viena iš mano mėgstamiausių vietų, kur naudoti sintaksę ** , kaip ir paskutiniame Dave Webb pavyzdyje:

 mynum = 1000 mystr = 'Hello World!' print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals()) 

Aš nesu įsitikinęs, kad tai yra labai greitas, palyginti su pačių pavadinimų naudojimu, tačiau tai yra daug lengviau įvesti!

67
03 авг. Wayne Werner atsakymas rugpjūčio 03 d 2010-08-03 16:03 '10, 16:03, 2010-08-03 16:03

Vienas atvejis yra, kai * args ir ** kwargs yra naudingi rašant įvyniojimo funkcijas (pvz., Dekoratorius), kurie turi sugebėti priimti savavališkus argumentus, kurie perduodami į suvyniotą funkciją. Pavyzdžiui, paprastas dekoratorius, kuris spausdina argumentus ir grąžina įvestos funkcijos vertę:

 def mydecorator( f ): @functools.wraps( f ) def wrapper( *args, **kwargs ): print "Calling f", args, kwargs v = f( *args, **kwargs ) print "f returned", v return v return wrapper 
40
03 авг. atsakymas duotas 03 rugpjūčio 3 d. 2010-08-03 11:40 '10, 11:40 val. 2010-08-03 11:40

* args ir ** kwargs yra specialios Python magijos funkcijos. Pagalvokite apie funkciją, kuri gali turėti nežinomą skaičių argumentų. Pavyzdžiui, dėl kokios nors priežasties norite turėti funkciją, kuri prideda nežinomą skaičių numerių (ir nenorite naudoti įmontuotos funkcijos sumos). Taigi rašote šią funkciją:

 def sumFunction(*args): result = 0 for x in args: result += x return result 

ir naudokite jį kaip: sumFunction (3,4,6,3,6,8,9).

** kwargs funkcija skiriasi. Naudodami ** kwargs, galite suteikti savavališkus argumentus funkcijų raktiniam žodžiui ir galite juos pasiekti kaip šaltinį.

 def someFunction(**kwargs): if 'text' in kwargs: print kwargs['text'] 

Skambinimas kai kurioms funkcijoms (text = "foo") bus spausdintas foo.

35
03 авг. atsakymas, kurį pateikė Steven Mohr 2010-08-03 11:40 '10, 11:40 val. 2010-08-03 11:40

Įsivaizduokite, kad turite funkciją, bet nenorite apriboti parametrų, kurių reikia, skaičius. Pavyzdys:

 >>> import operator >>> def multiply(*args): ... return reduce(operator.mul, args) 

Tada naudojate šią funkciją, pavyzdžiui:

 >>> multiply(1,2,3) 6 or >>> numbers = [1,2,3] >>> multiply(*numbers) 6 
17
03 авг. atsakymą pateikė Felix Kling 03 rug. 2010-08-03 11:40 '10, 11:40 val. 2010-08-03 11:40

Pavadinimai *args ir **kwargs arba **kw yra visiškai savavališki. Tai leidžia lengvai skaityti vienas kito kodą.

Viena vieta yra patogi naudoti naudojant struktūrinį modulį.

struct.unpack() grąžina struct.pack() , o struct.pack() - kintamas argumentų skaičius. Manipuliuojant duomenimis, patogu perkelti struck.pack() į struck.pack() .

 tuple_of_data = struct.unpack(format_str, data) ... manipulate the data new_data = struct.pack(format_str, *tuple_of_data) 

be šio gebėjimo jūs būsite priversti rašyti

 new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...) 

tai taip pat reiškia, kad jei format_str pakeitimai ir pakeitimų skaičius pasikeis, turėsiu grįžti ir redaguoti šią tikrai ilgą eilutę

15
03 авг. John La Rooy atsakymas rugpjūčio 03 d 2010-08-03 11:32 '10, 11:32, 2010-08-03 11:32

Atkreipkite dėmesį, kad * args / ** kwargs yra skambučių funkcijų sintaksės dalis ir nėra operatorius. Tai turi tam tikrą šalutinį poveikį, su kuriuo susidūriau, kad negalite naudoti args plėtinio su spausdinimo pareiškimu, nes spausdinimas nėra funkcija.

Tai atrodo pagrįsta:

 def myprint(*args): print *args 

Deja, ji nesudaro (sintaksės klaida).

Jis rengia:

 def myprint(*args): print args 

Tačiau spausdinami argumentai, kuriuos mes nenorime.

Tai sprendimas, kurį priėmiau:

 def myprint(*args): for arg in args: print arg, print 
9
11 нояб. Atsakymas pateikiamas yoyo 11.11. 2010-11-11 00:07 '10 - 0:07 2010-11-11 00:07

Šie parametrai paprastai naudojami proxy funkcijoms, todėl tarpinis serveris gali perduoti bet kokį tikslinės funkcijos įvesties parametrą.

 def foo(bar=2, baz=5): print bar, baz def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments print x foo(*args, **kwargs) # applies the "non-x" parameter to foo proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo proxy(6)# calls foo with its default arguments proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument 

Tačiau kadangi šie parametrai slopina faktinius parametrų pavadinimus, geriau juos išvengti.

7
03 авг. atsakymą pateikė Rudi 03 rug. 2010-08-03 11:41 '10, 11:41, 2010-08-03 11:41

Galite pažiūrėti „python“ dokumentus (docs.python.org DUK), bet tiksliau už paslaptingos „Miss Args“ ir „mister kwargs“ (archive.org) pasiteisinimą ( čia originalus, negyvas ryšys).

Trumpai tariant, abu naudojami, kai funkcijai ar metodui naudojami papildomi parametrai. Kaip sako Dave, * args naudojamas, kai nežinote, kiek argumentų galima perduoti, ir ** kwargs, kai norite apdoroti parametrus, nurodytus pagal pavadinimą ir vertę, kaip:

 myfunction(myarg=1) 
3
03 авг. atsakymas duotas Yoni H 03 rug. 2010-08-03 11:40 '10, 11:40 val. 2010-08-03 11:40

Kiti klausimai apie „ žymes arba užduoti klausimą