In che modo gli "argomenti di parole chiave" sono diversi dagli argomenti normali? Non è possibile passare tutti gli argomenti come name=value
anziché utilizzare la sintassi posizionale?
In che modo gli "argomenti di parole chiave" sono diversi dagli argomenti normali? Non è possibile passare tutti gli argomenti come name=value
anziché utilizzare la sintassi posizionale?
Risposte:
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'}
kwargs
o posso rinominarlo in sth. come options
( def my_fuction(arg1, arg2, **options)
)?
kwargs
sia la convenzione quando non esiste un nome più appropriato
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' *positional
argomento memorizzerà tutti gli argomenti posizionali passati foo()
, senza limiti a quanti ne puoi fornire.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
L' **keywords
argomento 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.
*positional
e **keywords
se 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.
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)
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)
Non hanno parole chiave prima di loro. L'ordine è importante!
func(1,2,3, "foo")
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)
func("bar", 5)
. E poi dire che hello
ottiene il suo valore predefinito di 3
.
Esistono due modi per assegnare i valori degli argomenti ai parametri della funzione, entrambi vengono utilizzati.
Per posizione. Gli argomenti posizionali non hanno parole chiave e vengono assegnati per primi.
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.
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
>>>
, **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.
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))
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.
Sono sorpreso che nessuno abbia menzionato il fatto che puoi mescolare argomenti posizionali e parole chiave per fare cose subdole come questa usando *args
e **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.
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 {}
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 *args
e **kwargs
in python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3