Argomenti normali e argomenti di parole chiave


289

In che modo gli "argomenti di parole chiave" sono diversi dagli argomenti normali? Non è possibile passare tutti gli argomenti come name=valueanziché utilizzare la sintassi posizionale?


6
Potresti anche leggere PEP 3102 - stanno sistemando alcune di queste cose in Python 3. Vedi: python.org/dev/peps/pep-3102
Ben Hoyt

E se un valore predefinito esiste o meno non ha nulla a che fare con esso (tranne se è necessario passarlo o meno), giusto?
MK

Maggiori informazioni sugli argomenti posizionali / parole chiave di
Python

@Ben Hoyt Aggiunta di seguito una risposta riguardante Python 3, argomenti delle parole chiave richiesti
Christophe Roussy,

Risposte:


346

Esistono due concetti correlati, entrambi chiamati " argomenti di parole chiave ".

Sul lato chiamante, che è quello che altri commentatori hanno menzionato, hai la possibilità di specificare alcuni argomenti di funzione per nome. Devi menzionarli dopo tutti gli argomenti senza nome ( argomenti posizionali ) e devono esserci valori predefiniti per tutti i parametri che non sono stati menzionati affatto.

L'altro concetto è sul lato della definizione della funzione: è possibile definire una funzione che accetta i parametri per nome e non è nemmeno necessario specificare quali sono quei nomi. Questi sono argomenti di parole chiave puri e non possono essere passati in posizione. La sintassi è

def my_function(arg1, arg2, **kwargs)

Qualsiasi argomento di parole chiave che passi a questa funzione verrà inserito in un dizionario chiamato kwargs. Puoi esaminare le chiavi di questo dizionario in fase di esecuzione, in questo modo:

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

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

{'a': 12, 'b': 'abc'}

5
+1 e accettato: sei l'unico che ha parlato di entrambi i tipi di argomenti posizionali + parole chiave, tutti gli altri pensavano che stessi parlando del primo o del secondo (ma erano comunque buoni post). Grazie!
MK

34
La formulazione non è chiara: normalmente si parla di argomenti sul lato chiamante mentre di parametri sul lato chiamato.
glglgl

3
Il nome del parametro deve essere kwargso posso rinominarlo in sth. come options( def my_fuction(arg1, arg2, **options))?
Bruce Sun

1
Il nome può essere qualsiasi cosa, sebbene kwargssia la convenzione quando non esiste un nome più appropriato
Matt Zimmerman,

Penso che il secondo concetto spiegato qui sia tecnicamente chiamato Argomenti per parole chiave arbitrarie.
Anshul Dahiya il

188

C'è un'ultima caratteristica della lingua in cui la distinzione è importante. Considera la seguente funzione:

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

L' *positionalargomento memorizzerà tutti gli argomenti posizionali passati foo(), senza limiti a quanti ne puoi fornire.

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

L' **keywordsargomento memorizzerà tutti gli argomenti delle parole chiave:

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

E, naturalmente, è possibile utilizzare entrambi contemporaneamente:

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

Queste funzionalità vengono utilizzate raramente, ma a volte sono molto utili ed è importante sapere quali argomenti sono posizionali o parole chiave.


3
Risposta eccellente! Solo una nota che gli argomenti posizionali richiesti possono essere passati prima *positionale **keywordsse cambiamo la definizione della funzione come def foo(arg1, *positional, **keywords):. Qui arg1è posizionale e richiesto. Si noti che posizionale nella risposta indica un numero facoltativo e variabile di argomenti posizionali.
Shaffooo,

2
Sì, bella risposta. Un'altra nota: se chiami la tua funzione foo(bar=True)puoi ottenere i valori usando lo bar = keywords.pop('bar')stesso di bar = keywords.pop('bar', None). Per valore predefinito, utilizzarebar = keywords.pop('bar', False)
olibre il

111

L'uso degli argomenti delle parole chiave è la stessa cosa degli argomenti normali, tranne per il fatto che l'ordine non ha importanza. Ad esempio le due funzioni chiamate di seguito sono le stesse:

def foo(bar, baz):
    pass

foo(1, 2)
foo(baz=2, bar=1)

3
Grazie per questo. È incredibilmente utile che sia sia possibile specificare una parola chiave arg come arg posizionale, sia un'arg posizionale come arg parola chiave.
Luke Davis,

47

Argomenti posizionali

Non hanno parole chiave prima di loro. L'ordine è importante!

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

Argomenti di parole chiave

Hanno parole chiave nella parte anteriore. Possono essere in qualsiasi ordine!

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

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

Dovresti anche sapere che se usi argomenti predefiniti e trascuri per inserire le parole chiave, l'ordine avrà importanza!

def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)

8
IMHO, il terzo esempio (argomenti predefiniti) non è chiaro. Penso che tu stia parlando di cosa succede quando uno o più parametri dichiarano valori predefiniti e la chiamata usa la notazione posizionale, ma fornisce MENO del numero di parametri dichiarati. Tuttavia, nel tuo esempio sono stati dichiarati 3 e 3 nella chiamata, quindi i valori predefiniti non hanno alcun effetto! Hai intenzione di omettere il terzo argomento. ad es func("bar", 5). E poi dire che helloottiene il suo valore predefinito di 3.
ToolmakerSteve

25

Esistono due modi per assegnare i valori degli argomenti ai parametri della funzione, entrambi vengono utilizzati.

  1. Per posizione. Gli argomenti posizionali non hanno parole chiave e vengono assegnati per primi.

  2. Per parola chiave. Gli argomenti delle parole chiave hanno parole chiave e vengono assegnati in secondo luogo, dopo gli argomenti posizionali.

Nota che hai la possibilità di usare argomenti posizionali.

Se si non si utilizza argomenti posizionali, poi - sì - tutto quello che si ha scritto si rivela essere un argomento parola chiave.

Quando si chiama una funzione, si decide di utilizzare la posizione, la parola chiave o una combinazione. Puoi scegliere di utilizzare tutte le parole chiave, se lo desideri. Alcuni di noi non fanno questa scelta e usano argomenti posizionali.


1
Ohh, stavo pensando a quello dei parametri, quando ciò che realmente è sono gli argomenti (ciò che passo). Grazie!
MK

24

Sono sorpreso che nessuno sembra aver sottolineato che si può passare un dizionario di parametri di argomenti chiave, che soddisfano i parametri formali, in questo modo.

>>> 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 per una tecnica utile. Il tuo punto sarebbe più chiaro, senza , **kwargs. Ciò dimostrerebbe che è possibile fornire un dizionario anche a una semplice funzione, con un numero fisso di parametri. Cioè, non richiede nulla di speciale nella definizione. POI potresti aggiungere un secondo esempio, CON ** kwargs nella definizione, e mostrare come gli elementi EXTRA nel dizionario sono disponibili tramite quello.
ToolmakerSteve

1
L'ho visto accadere nel codice sorgente di varie librerie ed ero così confuso. Grazie per averlo chiarito!
Craig Labenz,

3
Il quarto parametro formale sopra - ** kwargs è necessario se chiamate mai func con un dizionario che contiene chiavi diverse da 'a', 'b' e 'c'.
Eduardo,

Per me print 'a:%s, b:%s, c:%s' % (a, b, c)dà errore di sintassi, tuttavia print('a:%s, b:%s, c:%s' % (a, b, c))funziona. Qualcosa con la versione di Python? Comunque grazie per questa intuizione, fino ad ora stavo usando il più goffoprint('a:{}, b:{}, c:{}'.format(a, b, c))
Axel Bregnsbo il

17

Usando Python 3 puoi avere argomenti di parole chiave sia obbligatori che non obbligatori :


Opzionale : (valore predefinito definito per param 'b')

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

Richiesto (nessun valore predefinito definito per param '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'`

Questo può aiutare nei casi in cui hai molti argomenti simili uno accanto all'altro, specialmente se sono dello stesso tipo, in quel caso preferisco usare argomenti con nome o creo una classe personalizzata se gli argomenti appartengono insieme.


3
La variante richiesta è abbastanza utile. Esorta a dare gli argomenti per nome senza fornire le impostazioni predefinite, il che spesso non ha senso.
TNT,

I valori predefiniti hanno un bell'aspetto e possono aiutarti a risparmiare tempo quando inizi, ma a lungo termine i valori predefiniti possono essere una PITA.
Christophe Roussy,

11

Sono sorpreso che nessuno abbia menzionato il fatto che puoi mescolare argomenti posizionali e parole chiave per fare cose subdole come questa usando *argse **kwargs( da questo sito ):

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

Ciò consente di utilizzare argomenti di parole chiave arbitrari che potrebbero avere chiavi che non si desidera definire in anticipo.


0

Stavo cercando un esempio che avesse kwargs predefiniti usando l'annotazione di tipo:

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

esempio:

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

Basta implementare / aggiungere un modo per definire il valore predefinito degli argomenti che non è assegnato nelle parole chiave quando si chiama la funzione:

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

chiamalo come segue:

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

otterrai:

default_msg
love

leggi di più su *argse **kwargsin python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.