Nie rozumiem poniższego przykładu, powiedzmy, że mam te funkcje:
# python likes
def save(filename, data, **kwargs):
fo = openX(filename, "w", **kwargs) # <- #1
fo.write(data)
fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
fo = openX(filename, "w", kwargs) # <- #2
fo.write(data)
fo.close()
def openX(filename, mode, **kwargs):
#doing something fancy and returning a file object
Dlaczego nr 1 jest właściwym rozwiązaniem, a nr 2 niewłaściwym? **kwargs
jest w zasadzie dyktando, więc jeśli chcę przekazać argument do openX, myślę, że właściwy sposób byłby bez **
i po prostu podając dyktando. Ale Python oczywiście nie lubi drugiego i mówi mi, że podałem 3 zamiast 2 argumentów. Więc jaki jest tego powód?
**args
w kodzie. To prawdopodobnie najgorsza możliwa nazwa, z którą ludzie będą je mylić*args
Odpowiedzi:
W drugim przykładzie podajesz 3 argumenty: nazwa pliku, tryb i słownik (
kwargs
). Ale Python oczekuje: 2 argumentów formalnych plus argumenty słów kluczowych.Przedrostkiem słownika „**” można rozpakować słownik
kwargs
na argumenty słów kluczowych.Słownik (typ
dict
) to pojedyncza zmienna zawierająca pary klucz-wartość.„Argumenty słów kluczowych” to para klucz-wartość parametrów metody.
Każdy słownik można rozpakować jako argumenty słów kluczowych, poprzedzając go
**
podczas wywołania funkcji.źródło
**
Składnia mówi Python zebrać argumenty słowa kluczowego w słowniku.save2
Przechodzi go jako argumentu niż słowa kluczowego (słownikiem obiektu).openX
Nie widzi żadnych argumentów słów kluczowych, więc**args
nie przyzwyczaić. Zamiast tego pobiera trzeci argument niebędący słowem kluczowym (słownik). Aby to naprawić, zmień definicjęopenX
funkcji.źródło
Rozwijając odpowiedź @gecco, poniżej znajduje się przykład, który pokaże różnicę:
Tutaj możesz zobaczyć, jak działa rozpakowywanie słownika i dlaczego wysłanie rzeczywistego słownika kończy się niepowodzeniem
źródło
Ponieważ słownik to pojedyncza wartość. Musisz użyć rozszerzenia słów kluczowych, jeśli chcesz przekazać je jako grupę argumentów słów kluczowych.
źródło
Dla # 2 argumenty będą tylko formalnym parametrem z wartością dict, ale nie będą parametrem typu słowa kluczowego.
Jeśli chcesz przekazać parametr typu słowa kluczowego do argumentu słowa kluczowego, musisz określić ** przed swoim słownikiem, co oznacza ** argumenty
sprawdź to, aby uzyskać więcej informacji na temat używania ** kw
http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
źródło