Argumenty normalne a argumenty słów kluczowych

290

Czym różnią się „argumenty słów kluczowych” od zwykłych argumentów? Czy nie można przekazać wszystkich argumentów jako name=valuezamiast używania składni pozycyjnej?

mk12
źródło
6
Możesz także przeczytać PEP 3102 - porządkują niektóre z tych rzeczy w Pythonie 3. Patrz: python.org/dev/peps/pep-3102
Ben Hoyt
I to, czy istnieje wartość domyślna, nie ma z tym nic wspólnego (z wyjątkiem tego, czy potrzebujesz jej przekazać), prawda?
mk12
Przeczytaj więcej o argumentach pozycyjnych / słowach kluczowych w
pythonie
@Ben Hoyt Dodano odpowiedź poniżej obejmującą Python 3, wymagane argumenty słów kluczowych
Christophe Roussy

Odpowiedzi:

347

Istnieją dwa powiązane pojęcia, oba nazywane „ argumentami słów kluczowych ”.

Po stronie wywołującej, o której wspominali inni komentatorzy, możesz podać niektóre argumenty funkcji według nazwy. Musisz wymienić je po wszystkich argumentach bez nazw ( argumenty pozycyjne ) i muszą istnieć wartości domyślne dla parametrów, które w ogóle nie zostały wymienione.

Druga koncepcja dotyczy definicji funkcji: możesz zdefiniować funkcję, która pobiera parametry według nazwy - i nie musisz nawet określać, jakie są te nazwy. Są to czyste argumenty słów kluczowych i nie można ich przekazywać pozycyjnie. Składnia jest następująca

def my_function(arg1, arg2, **kwargs)

Wszelkie argumenty słów kluczowych przekazane do tej funkcji zostaną umieszczone w słowniku o nazwie kwargs. Możesz sprawdzić klucze tego słownika w czasie wykonywania, w następujący sposób:

def my_function(**kwargs):
    print str(kwargs)

my_function(a=12, b="abc")

{'a': 12, 'b': 'abc'}
Ian Clelland
źródło
5
+1 i zaakceptowano: jesteś jedynym, który mówił o obu typach argumentów pozycyjnych + słów kluczowych, wszyscy inni myśleli, że mówię o pierwszym lub drugim (ale wciąż były to dobre posty). Dzięki!
mk12
34
Sformułowanie jest niejasne: zwykle mówi się o argumentach po stronie wywołującej, a o parametrach po stronie wywoływanej.
glglgl 14.10.12
3
Czy nazwa parametru musi być, kwargsczy mogę zmienić nazwę na sth. jak options( def my_fuction(arg1, arg2, **options))?
Bruce Sun,
1
Nazwa może być dowolna, ale kwargsjest konwencją, gdy nie ma bardziej odpowiedniej nazwy
Matt Zimmerman
Myślę, że druga koncepcja wyjaśniona tutaj jest technicznie nazywana Arbitralnym Kluczowym Argumentem.
Anshul Dahiya,
188

Jest jeszcze jedna ostatnia cecha językowa, w której rozróżnienie jest ważne. Rozważ następującą funkcję:

def foo(*positional, **keywords):
    print "Positional:", positional
    print "Keywords:", keywords

*positionalArgumentem będzie przechowywać wszystkie argumenty przekazywane do pozycyjnych foo(), bez limitu do ilu można zapewnić.

>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}

**keywordsArgumentem będzie przechowywać żadnych argumentów słowa kluczowego:

>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}

I oczywiście możesz korzystać z obu jednocześnie:

>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}

Te funkcje są rzadko używane, ale czasami są bardzo przydatne i ważne jest, aby wiedzieć, które argumenty są pozycjonujące lub słowa kluczowe.

za dużo php
źródło
3
Doskonała odpowiedź! Tylko uwaga, że ​​wymagane argumenty pozycyjne można przekazać wcześniej *positionali **keywordsjeśli zmienimy definicję funkcji jak def foo(arg1, *positional, **keywords):. Tutaj arg1jest pozycyjny i wymagany. Pamiętaj, że pozycja pozycyjna w odpowiedzi oznacza opcjonalną i zmienną liczbę argumentów pozycyjnych.
shaffooo
2
Tak dobra odpowiedź. Kolejna uwaga: jeśli wywołasz swoją funkcję foo(bar=True), możesz uzyskać wartości używając takich bar = keywords.pop('bar')samych jak bar = keywords.pop('bar', None). Aby uzyskać wartość domyślną, użyjbar = keywords.pop('bar', False)
olibre
111

Używanie argumentów słów kluczowych jest tym samym, co zwykłe argumenty, tyle że kolejność nie ma znaczenia. Na przykład dwie poniższe funkcje są takie same:

def foo(bar, baz):
    pass

foo(1, 2)
foo(baz=2, bar=1)
Eli Gray
źródło
3
Dzięki za to. Niezwykle przydatne jest to, że mogę zarówno podać słowo kluczowe arg jako argument pozycyjny, jak i arg pozycyjny jako słowo kluczowe arg.
Luke Davis,
47

Argumenty pozycyjne

Nie mają przed nimi słów kluczowych. Kolejność jest ważna!

func(1,2,3, "foo")

Argumenty słów kluczowych

Mają słowa kluczowe z przodu. Mogą być w dowolnej kolejności!

func(foo="bar", baz=5, hello=123)

func(baz=5, foo="bar", hello=123)

Powinieneś także wiedzieć, że jeśli użyjesz domyślnych argumentów i zaniedbasz wstawianie słów kluczowych, wtedy kolejność będzie miała znaczenie!

def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
Nieznany
źródło
8
IMHO, trzeci przykład (domyślne argumenty) nie jest jasny. Myślę, że mówisz o tym, co się dzieje, gdy co najmniej jeden parametr deklaruje wartości domyślne, a wywołanie używa notacji pozycyjnej, ale dostarcza MNIEJ niż liczba deklarowanych parametrów. Jednak twój przykład ma 3 zadeklarowane i 3 w wywołaniu, więc wartości domyślne nie mają żadnego wpływu! Czy zamierzasz pominąć trzeci argument? na przykład func("bar", 5)? A potem powiedzmy, że hellootrzymuje domyślną wartość 3.
ToolmakerSteve,
25

Istnieją dwa sposoby przypisywania wartości argumentów do parametrów funkcji, oba są używane.

  1. Według pozycji. Argumenty pozycyjne nie mają słów kluczowych i są przypisywane jako pierwsze.

  2. Według słowa kluczowego. Argumenty słów kluczowych zawierają słowa kluczowe i są przypisywane jako drugie, po argumentach pozycyjnych.

Zauważ, że masz opcję użycia argumentów pozycyjnych.

Jeśli ty nie używać argumentów pozycyjnych, a następnie - tak - wszystko Ci napisałem okazuje się być argumentem kluczowym.

Kiedy ty wywołać funkcję w podjęciu decyzji do pozycji użytkowej lub słowa kluczowego lub mieszaniny. Jeśli chcesz, możesz wybrać wykonanie wszystkich słów kluczowych. Niektórzy z nas nie dokonują tego wyboru i używają argumentów pozycyjnych.

S.Lott
źródło
1
Och, myślałem o parametrach, kiedy tak naprawdę to są argumenty (to , co przekazuję). Dzięki!
mk12
24

Dziwi mnie, że nikt nie zauważył, że można przekazać słownik kluczowych parametrów argumentu, które spełniają parametry formalne.

>>> def func(a='a', b='b', c='c', **kwargs):
...    print 'a:%s, b:%s, c:%s' % (a, b, c)
... 
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>> 
Sherman
źródło
11
+1 za przydatną technikę. Twój punkt byłby jaśniejszy bez , **kwargs. To pokazałoby, że nawet prosty func def, ze stałą liczbą parametrów, może być dostarczony ze słownikiem. Oznacza to, że nie wymaga nic szczególnego w definicji. NASTĘPNIE możesz dodać drugi przykład, Z ** kwargs w definicji, i pokazać, w jaki sposób elementy EXTRA w słowniku są dostępne za jego pośrednictwem.
ToolmakerSteve,
1
Widziałem to w kodzie źródłowym różnych bibliotek i byłem bardzo zdezorientowany. Dzięki za wyjaśnienie!
Craig Labenz
3
Czwarty parametr formalny powyżej - ** kwargs jest konieczny, jeśli kiedykolwiek wywołasz func ze słownikiem zawierającym klucze inne niż „a”, „b” i „c”.
Eduardo,
Dla mnie print 'a:%s, b:%s, c:%s' % (a, b, c)podaje błąd składniowy, jednak print('a:%s, b:%s, c:%s' % (a, b, c))działa. Coś z wersją Python? W każdym razie dzięki za ten wgląd, do tej pory korzystałem z bardziej print('a:{}, b:{}, c:{}'.format(a, b, c))
niezręcznej
17

Korzystanie Python 3 można mieć zarówno wymagane, a nie wymaganych słów kluczowych argumentów :


Opcjonalne : (wartość domyślna zdefiniowana dla parametru „b”)

def func1(a, *, b=42):
    ...
func1(value_for_a) # b is optional and will default to 42

Wymagane (nie zdefiniowano wartości domyślnej dla parametru „b”):

def func2(a, *, b):
    ... 
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`

Może to pomóc w przypadkach, gdy masz wiele podobnych argumentów obok siebie, szczególnie jeśli są one tego samego typu, w takim przypadku wolę używać nazwanych argumentów lub tworzę niestandardową klasę, jeśli argumenty należą do siebie.

Christophe Roussy
źródło
3
Wymagany wariant jest bardzo przydatna. Wzywa do podania argumentów z nazwy bez podawania wartości domyślnych, co często nie ma sensu.
TNT
Wartości domyślne wyglądają ładnie i mogą pomóc Ci zaoszczędzić czas na starcie, ale na dłuższą metę wartości domyślne mogą być PITA.
Christophe Roussy,
11

Dziwię się, że nikt nie wspominał o tym, że można łączyć argumenty pozycyjne i słowa kluczowego, aby robić podstępne rzeczy przy użyciu *argsi **kwargs( z tej strony ):

def test_var_kwargs(farg, **kwargs):
    print "formal arg:", farg
    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

Pozwala to na użycie dowolnych argumentów słów kluczowych, które mogą mieć klucze, których nie chcesz definiować z góry.

Gabriel Hurley
źródło
0

Szukałem przykładu z domyślnymi kwargsami wykorzystującymi adnotacje typu:

def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
     return ' '.join([a, b, c, str(kwargs)])

przykład:

>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
jmunsch
źródło
0

Wystarczy uzupełnić / dodać sposób definiowania domyślnej wartości argumentów, które nie są przypisywane słowami kluczowymi podczas wywoływania funkcji:

def func(**keywargs):
if 'my_word' not in keywargs:
    word = 'default_msg'
else:
    word = keywargs['my_word']
return word

nazwij to przez:

print(func())
print(func(my_word='love'))

dostaniesz:

default_msg
love

czytaj więcej na temat *argsoraz **kwargsw python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

sonictl
źródło