W poniższych definicjach metod do czego służy *
i **
do czego służy param2
?
def foo(param1, *param2):
def bar(param1, **param2):
W poniższych definicjach metod do czego służy *
i **
do czego służy param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Aby dowiedzieć się, co to znaczy w wywołaniach funkcji (func(*[1,2])
), zobacz tutaj . Aby dowiedzieć się, jak rozpakować listę argumentów, zobacz tutaj . W przypadku pytania dotyczącego*
znaczenia literałów ([*[1, 2]]
) patrz tutaj .Odpowiedzi:
*args
I**kwargs
jest wspólny idiom, aby umożliwić dowolną liczbę argumentów do funkcji opisanych w sekcji więcej na temat definiowania funkcji w dokumentacji Pythona.*args
Daje wszystkie parametry funkcyjne jak krotki :**kwargs
Daje wszystkie argumenty słów kluczowych z wyjątkiem tych, co odpowiada parametru formalnego jako słownika.Oba idiomy można łączyć z normalnymi argumentami, aby umożliwić zestaw stałych i niektórych zmiennych argumentów:
Można również użyć tego na odwrót:
Innym zastosowaniem tego
*l
idiomu jest rozpakowywanie list argumentów podczas wywoływania funkcji.W Pythonie 3 można używać
*l
po lewej stronie zadania ( Extended Iterable Unpacking ), chociaż w tym kontekście daje listę zamiast krotki:Również Python 3 dodaje nowy semantyczny (patrz PEP 3102 ):
Taka funkcja przyjmuje tylko 3 argumenty pozycyjne, a wszystko później
*
można przekazać tylko jako argumenty słów kluczowych.źródło
**kwargs
odpowiada teraz kolejności, w której argumenty słów kluczowych zostały przekazane do funkcji.” - docs.python.org/3/whatsnew/3.6.html W rzeczywistości wszystkie nagrania w CPython 3.6 zapamiętują kolejność wstawiania jako szczegół implementacji, co staje się standardem w Pythonie 3.7.got an unexpected keyword argument 'name'
Warto również zauważyć, że możesz używać
*
i**
podczas wywoływania funkcji. Jest to skrót, który pozwala przekazać wiele argumentów do funkcji bezpośrednio przy użyciu listy / krotki lub słownika. Na przykład, jeśli masz następującą funkcję:Możesz robić takie rzeczy jak:
Uwaga: Klucze w
mydict
muszą być nazwane dokładnie tak, jak parametry funkcjifoo
. W przeciwnym razie wyrzuciTypeError
:źródło
Pojedyncza * oznacza, że może istnieć dowolna liczba dodatkowych argumentów pozycyjnych.
foo()
można wywołać jakfoo(1,2,3,4,5)
. W treści foo () param2 jest sekwencją zawierającą 2-5.Podwójna ** oznacza, że może istnieć dowolna liczba dodatkowych nazwanych parametrów.
bar()
można wywołać jakbar(1, a=2, b=3)
. W treści bar () param2 znajduje się słownik zawierający {'a': 2, 'b': 3}Z następującym kodem:
wyjście jest
źródło
foobar(param1, *param2, **param3)
potrzebny jest dodatkowy przykład z kompletnością tej odpowiedzi.Umożliwiają zdefiniowanie funkcji do zaakceptowania, a użytkownikom przekazanie dowolnej liczby argumentów, pozycyjnej (
*
) i słowa kluczowego (**
).Definiowanie funkcji
*args
dopuszcza dowolną liczbę opcjonalnych argumentów pozycyjnych (parametrów), które zostaną przypisane do krotki o nazwieargs
.**kwargs
dopuszcza dowolną liczbę opcjonalnych argumentów (parametrów) słowa kluczowego, które będą w nazwie o nazwiekwargs
.Możesz (i powinieneś) wybrać dowolną odpowiednią nazwę, ale jeśli intencją jest, aby argumenty miały nieswoistą semantykę
args
ikwargs
były standardowymi nazwami.Rozbudowa, przekazanie dowolnej liczby argumentów
Możesz także użyć
*args
i**kwargs
do przekazania parametrów odpowiednio z list (lub dowolnej iterowalnej) i dykt (lub dowolnego odwzorowania).Funkcja odbierająca parametry nie musi wiedzieć, że są one rozszerzane.
Na przykład xrange w Pythonie 2 nie oczekuje wprost
*args
, ale ponieważ jako argument przyjmuje 3 liczby całkowite:Jako kolejny przykład możemy użyć rozszerzenia dict w
str.format
:Nowość w Python 3: Definiowanie funkcji za pomocą argumentów zawierających tylko słowa kluczowe
Możesz mieć tylko słowa kluczowe jako argumenty - po,
*args
na przykład, tutajkwarg2
musisz podać jako słowo kluczowe - nie pozycjonować:Stosowanie:
Ponadto,
*
może być stosowany przez siebie słów kluczowych, aby wskazać, że tylko argumenty naśladowania, nie pozwalając na nieograniczone pozycyjnych argumentów.Tutaj
kwarg2
znowu musi być jawnie nazwany argument słowa kluczowego:Nie możemy dłużej akceptować nieograniczonej liczby argumentów pozycyjnych, ponieważ nie mamy
*args*
:Ponownie, prościej, tutaj wymagamy
kwarg
podania imienia, a nie pozycji:W tym przykładzie widzimy, że jeśli spróbujemy przekazać
kwarg
pozycję, otrzymujemy błąd:Musimy jawnie przekazać
kwarg
parametr jako argument słowa kluczowego.Dema kompatybilne z Python 2
*args
(zwykle mówi się „star-args”) i**kwargs
(gwiazdy można sugerować, mówiąc „kwargs”, ale wyraźne w przypadku „podwójnej gwiazdy kwargs”) są powszechnymi idiomami Pythona do używania*
i**
notacji. Te specyficzne nazwy zmiennych nie są wymagane (np. Możesz użyć*foos
i**bars
), ale odejście od konwencji prawdopodobnie rozwścieczy innych koderów Pythona.Zazwyczaj używamy ich, gdy nie wiemy, co otrzyma nasza funkcja lub ile argumentów możemy przekazać, a czasami nawet gdy nazewnictwo każdej zmiennej osobno byłoby bardzo nieporządne i zbędne (ale jest to przypadek, w którym zwykle jawne jest lepszy niż dorozumiany).
Przykład 1
Poniższa funkcja opisuje, w jaki sposób można ich używać, i pokazuje zachowanie. Uwaga: nazwany
b
argument zostanie wykorzystany przez drugi argument pozycyjny przed:Możemy sprawdzić pomoc online dla podpisu funkcji, za pomocą
help(foo)
, który nam to mówiNazwijmy tę funkcję za pomocą
foo(1, 2, 3, 4, e=5, f=6, g=7)
który drukuje:
Przykład 2
Możemy również wywołać go za pomocą innej funkcji, w której zapewniamy
a
:bar(100)
drukuje:Przykład 3: praktyczne zastosowanie w dekoratorach
OK, więc może jeszcze nie widzimy narzędzia. Wyobraź sobie, że masz kilka funkcji z kodem nadmiarowym przed i / lub po kodzie różnicującym. Poniższe nazwane funkcje to tylko pseudo-kod do celów ilustracyjnych.
Możemy być w stanie poradzić sobie z tym inaczej, ale z pewnością możemy wydobyć nadmiarowość za pomocą dekoratora, dlatego nasz poniższy przykład pokazuje, jak
*args
i**kwargs
może być bardzo przydatny:A teraz każdą zawiniętą funkcję można napisać o wiele bardziej zwięźle, ponieważ uwzględniliśmy redundancję:
Oraz faktoringu nasz kod, który
*args
i**kwargs
pozwala nam zrobić, to zmniejszyć linii kodu, poprawiają czytelność i łatwość konserwacji i mają wyłączne kanoniczne lokalizacje dla logiki w naszym programie. Jeśli potrzebujemy zmienić dowolną część tej struktury, mamy jedno miejsce, w którym można dokonać każdej zmiany.źródło
Najpierw zrozumiemy, czym są argumenty pozycyjne i argumenty słów kluczowych. Poniżej znajduje się przykład definicji funkcji z argumentami Pozycyjnymi.
To jest definicja funkcji z argumentami pozycyjnymi. Możesz to również wywołać za pomocą argumentów słowo kluczowe / nazwane:
Przeanalizujmy teraz przykład definicji funkcji z argumentami słów kluczowych :
Możesz wywołać tę funkcję również z argumentami pozycyjnymi:
Znamy więc definicje funkcji z argumentami pozycyjnymi i słowami kluczowymi.
Przyjrzyjmy się teraz operatorowi „*” i operatorowi „**”.
Uwaga: tych operatorów można używać w 2 obszarach:
a) wywołanie funkcji
b) definicja funkcji
Zastosowanie operatora „*” i operatora „**” w wywołaniu funkcji.
Przejdźmy od razu do przykładu, a następnie go omówmy.
Więc pamiętaj
gdy w wywołaniu funkcji używany jest operator „*” lub „**” -
Operator „*” rozpakowuje strukturę danych, na przykład listę lub krotkę, na argumenty potrzebne do definicji funkcji.
Operator „**” rozpakowuje słownik na argumenty potrzebne do definicji funkcji.
Przeanalizujmy teraz użycie operatora „*” w definicji funkcji . Przykład:
W definicji funkcji operator „*” pakuje otrzymane argumenty do krotki.
Zobaczmy teraz przykład „**” zastosowany w definicji funkcji:
W definicji funkcji Operator „**” pakuje odebrane argumenty do słownika.
Więc pamiętaj:
W wywołaniu funkcji „*” rozpakowuje strukturę danych krotki lub listy na argumenty pozycyjne lub słowa kluczowe, które mają zostać odebrane przez definicję funkcji.
W wywołaniu funkcji „**” rozpakowuje strukturę danych słownika na argumenty pozycyjne lub słowa kluczowe, które mają zostać odebrane przez definicję funkcji.
W definicji funkcji „*” pakuje argumenty pozycyjne w krotkę.
W definicji funkcji „**” pakuje argumenty słów kluczowych do słownika.
źródło
Ta tabela jest przydatna do używania
*
oraz**
w budowie funkcji i wywołaniu funkcji :To tak naprawdę służy do podsumowania Lorina Hochstein za odpowiedź , ale uważam, że pomocne.
Odpowiednio: zastosowania dla operatorów gwiazda / ikona zostały rozszerzone w Pythonie 3
źródło
*
i**
mają specjalne zastosowanie na liście argumentów funkcji.*
implikuje, że argument jest listą i**
implikuje, że argument jest słownikiem. Umożliwia to funkcjom przyjmowanie dowolnej liczby argumentówźródło
Dla tych z was, którzy uczą się na przykładach!
*
jest umożliwienie zdefiniowania funkcji, która może przyjąć dowolną liczbę argumentów podanych jako lista (npf(*myList)
.).**
to na celu umożliwienie podawania argumentów funkcji przez udostępnienie słownika (npf(**{'x' : 1, 'y' : 2})
.).Pokażmy to definiując funkcję, która pobiera dwa normalne zmienne
x
,y
i może przyjąć więcej argumentów, jakmyArgs
i może przyjąć jeszcze więcej argumentów jakmyKW
. Później pokażemy, jak karmićy
za pomocąmyArgDict
.Ostrzeżenia
**
jest zarezerwowane wyłącznie dla słowników.**
musi*
zawsze nastąpić później .źródło
Z dokumentacji Python:
źródło
*
oznacza odbieranie zmiennych argumentów jako krotki**
oznacza odbieranie zmiennych argumentów jako słownikUżywany w następujący sposób:
1) pojedynczy *
Wynik:
2) Teraz
**
Wynik:
źródło
Chcę podać przykład, o którym inni nie wspominali
* można również rozpakować generator
Przykład z dokumentu Python3
unzip_x wyniesie [1, 2, 3], unzip_y wyniesie [4, 5, 6]
Zip () odbiera wiele możliwych do zapisania argumentów i zwraca generator.
źródło
W Pythonie 3.5, można również użyć tej składni w
list
,dict
,tuple
iset
wyświetlenia (zwany też czasami literałów). Zobacz PEP 488: Dodatkowe uogólnienia dotyczące rozpakowywania .Umożliwia także rozpakowanie wielu iteracji w jednym wywołaniu funkcji.
(Podziękowania dla mgilson za link PEP.)
źródło
Oprócz wywołań funkcji, * args i ** kwargs są przydatne w hierarchiach klas, a także unikają konieczności pisania
__init__
metod w Pythonie. Podobne użycie można zobaczyć w ramach takich jak kod Django.Na przykład,
Wówczas może być podklasa
Następnie należy utworzyć instancję podklasy jako
Ponadto podklasa z nowym atrybutem, która ma sens tylko dla tej instancji podklasy, może wywoływać klasę Base w
__init__
celu odciążenia ustawienia atrybutów. Odbywa się to za pomocą * args i ** kwargs. kwargs używane głównie, aby kod był czytelny przy użyciu nazwanych argumentów. Na przykład,który może być zaimplementowany jako
Pełny kod jest tutaj
źródło
Opierając się na odpowiedzi Nickda ...
Wynik:
Zasadniczo dowolna liczba argumentów pozycyjnych może używać * argumentów, a dowolne nazwane argumenty (lub argumenty kwargs zwane również argumentami słów kluczowych) mogą używać ** kwargs.
źródło
*args
i**kwargs
: pozwala przekazać zmienną liczbę argumentów do funkcji.*args
: służy do wysłania listy argumentów o zmiennej długości bez słów kluczowych do funkcji:Będzie produkować:
**kwargs*
**kwargs
pozwala na przekazanie funkcji zmiennej o zmiennej długości argumentów. Powinieneś użyć,**kwargs
jeśli chcesz obsługiwać nazwane argumenty w funkcji.Będzie produkować:
źródło
Ten przykład pomoże ci zapamiętać
*args
,**kwargs
a nawetsuper
odziedziczyć w Pythonie naraz.źródło
Dobrym przykładem użycia obu funkcji jest:
źródło
TL; DR
Poniżej 6 różnych przypadków użycia dla
*
i**
w programowaniu Pythona:*args
:def foo(*args): pass
tufoo
przyjmuje dowolną liczbę argumentów pozycyjnych, czyli następujące połączenia są prawidłowefoo(1)
,foo(1, 'bar')
**kwargs
:def foo(**kwargs): pass
tutaj „foo” akceptuje dowolną liczbę argumentów słów kluczowych, tj. Prawidłowe są następujące wywołaniafoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:def foo(*args, **kwargs): pass
, tutajfoo
przyjmuje dowolną liczbę argumentów pozycyjnych i słów kluczowych, czyli następujące połączenia są prawidłowefoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:def foo(pos1, pos2, *, kwarg1): pass
tutaj*
oznacza, że foo akceptować tylko argumenty słów kluczowych po pos2, stądfoo(1, 2, 3)
podnosi TypeError alefoo(1, 2, kwarg1=3)
jest w porządku.*_
(Uwaga: to tylko konwencja):def foo(bar, baz, *_): pass
oznacza (zgodnie z konwencją)foo
tylko użyciebar
ibaz
argumenty w działaniu i zignoruje inne.\**_
(Uwaga: jest to tylko konwencja):def foo(bar, baz, **_): pass
oznacza (zgodnie z konwencją)foo
tylko użyciebar
ibaz
argumenty w działaniu i zignoruje inne.BONUS: Począwszy od Pythona 3.8, można używać
/
definicji funkcji do wymuszania parametrów tylko pozycyjnych. W poniższym przykładzie parametry aib są tylko pozycyjne , podczas gdy c lub d może być pozycyjne lub słowo kluczowe, a e lub f muszą być słowami kluczowymi:źródło
TL; DR
Pakuje argumenty przekazane do funkcji do
list
idict
odpowiednio wewnątrz treści funkcji. Po zdefiniowaniu podpisu funkcji w ten sposób:można go wywołać z dowolną liczbą argumentów i argumentów słów kluczowych. Argumenty niebędące słowami kluczowymi są pakowane w listę wywoływaną
args
w treści funkcji, a argumenty słów kluczowych są pakowane w dykt wywoływanykwds
w treści funkcji.teraz w ciele funkcji, gdy funkcja jest wywoływana, istnieją dwie zmienne lokalne,
args
która jest listą o wartości["this", "is a list of", "non-keyword", "arguments"]
ikwds
któradict
ma wartość{"keyword" : "ligma", "options" : [1,2,3]}
Działa to również w odwrotnej kolejności, tj. Po stronie dzwoniącego. na przykład, jeśli masz funkcję zdefiniowaną jako:
możesz to wywołać przez rozpakowanie iteracji lub mapowań, które masz w zakresie wywoływania:
źródło
Kontekst
**
Używaj z formatowaniem ciągów
Oprócz odpowiedzi w tym wątku, oto kolejny szczegół, który nie został wymieniony w innym miejscu. Rozszerza to odpowiedź Brada Solomona
Rozpakowywanie za pomocą
**
jest również przydatne w przypadku używania Pythonastr.format
.Jest to nieco podobne do tego, co można zrobić z ciągiem f Pythona
f-strings
ale z dodatkowym obciążeniem wynikającym z deklarowania, że dict przechowuje zmienne (ciąg f nie wymaga dyktowania).Szybki przykład
źródło
def foo(param1, *param2):
to metoda może zaakceptować dowolną liczbę wartości dla*param2
,def bar(param1, **param2):
to metoda może zaakceptować dowolną liczbę wartości za pomocą kluczy*param2
param1
jest prostym parametrem.Na przykład składnia do implementacji varargs w Javie jest następująca:
źródło