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?


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


@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'}

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.


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)

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)

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.


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

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.


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.


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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.