Qual a diferença entre "argumentos de palavras-chave" e argumentos regulares? Todos os argumentos não podem ser passados como em name=value
vez de usar a sintaxe posicional?
Qual a diferença entre "argumentos de palavras-chave" e argumentos regulares? Todos os argumentos não podem ser passados como em name=value
vez de usar a sintaxe posicional?
Respostas:
Existem dois conceitos relacionados, ambos chamados " argumentos de palavras-chave ".
No lado de chamada, que é o que outros comentadores mencionaram, você pode especificar alguns argumentos de função por nome. Você deve mencioná-los depois de todos os argumentos sem nomes ( argumentos posicionais ) e deve haver valores padrão para quaisquer parâmetros que não foram mencionados.
O outro conceito está no lado da definição de função: você pode definir uma função que aceita parâmetros por nome - e nem precisa especificar quais são esses nomes. Estes são argumentos puros de palavras-chave e não podem ser passados posicionalmente. A sintaxe é
def my_function(arg1, arg2, **kwargs)
Qualquer argumento de palavra-chave que você passar para esta função será colocado em um dicionário chamado kwargs
. Você pode examinar as chaves deste dicionário em tempo de execução, assim:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
kwargs
ou posso renomeá-lo para sth. like options
( def my_fuction(arg1, arg2, **options)
)?
kwargs
é a convenção quando não há um nome mais apropriado
Há um último recurso de idioma em que a distinção é importante. Considere a seguinte função:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
O *positional
argumento armazenará todos os argumentos posicionais passados para foo()
, sem limite para quantos você pode fornecer.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
O **keywords
argumento armazenará qualquer argumento de palavra-chave:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
E é claro, você pode usar os dois ao mesmo tempo:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
Esses recursos raramente são usados, mas ocasionalmente são muito úteis e é importante saber quais argumentos são posicionais ou palavras-chave.
*positional
e **keywords
se mudarmos a definição de função como def foo(arg1, *positional, **keywords):
. Aqui arg1
é posicional e obrigatório. Observe que a resposta posicional significa número opcional e variável de argumentos posicionais.
foo(bar=True)
poderá obter os valores usando o bar = keywords.pop('bar')
mesmo que bar = keywords.pop('bar', None)
. Para o valor padrão, usebar = keywords.pop('bar', False)
Usar argumentos de palavra-chave é a mesma coisa que argumentos normais, exceto que a ordem não importa. Por exemplo, as duas chamadas de funções abaixo são as mesmas:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
Eles não têm palavras-chave antes deles. A ordem é importante!
func(1,2,3, "foo")
Eles têm palavras-chave na frente. Eles podem estar em qualquer ordem!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
Você também deve saber que, se você usar argumentos padrão e negligenciar a inserção das palavras-chave, o pedido será importante!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
func("bar", 5)
? E então diga que hello
obtém seu valor padrão de 3
.
Existem duas maneiras de atribuir valores de argumento aos parâmetros de função, ambos são usados.
Por posição. Argumentos posicionais não possuem palavras-chave e são atribuídos primeiro.
Por palavra-chave. Os argumentos de palavra-chave possuem palavras-chave e são atribuídos em segundo lugar, após argumentos posicionais.
Observe que você tem a opção de usar argumentos posicionais.
Se você não usar argumentos posicionais, tudo o que você escreveu será um argumento de palavra-chave.
Quando você chamar uma função de tomar uma decisão para a posição de utilização ou palavra-chave ou uma mistura. Você pode optar por fazer todas as palavras-chave, se quiser. Alguns de nós não fazem essa escolha e usam argumentos posicionais.
Estou surpreso que ninguém parece ter apontado que alguém pode passar um dicionário de parâmetros de argumento com chave, que satisfazem os parâmetros formais, assim.
>>> 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
. Isso demonstraria que mesmo um simples func def, com um número fixo de parâmetros, pode receber um dicionário. Ou seja, não requer nada sofisticado na definição. ENTÃO, você pode adicionar um segundo exemplo, WITH ** kwargs na definição, e mostrar como os itens EXTRA no dicionário estão disponíveis por meio disso.
print 'a:%s, b:%s, c:%s' % (a, b, c)
dá erro de sintaxe, no entanto print('a:%s, b:%s, c:%s' % (a, b, c))
funciona. Algo com a versão Python? De qualquer forma, obrigado por essa visão, até agora eu estava usando o mais desajeitadoprint('a:{}, b:{}, c:{}'.format(a, b, c))
Usando Python 3 você pode ter ambos palavra-chave necessários e não necessários argumentos :
Opcional : (valor padrão definido para o parâmetro 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Necessário (nenhum valor padrão definido para o parâmetro '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'`
Isso pode ajudar nos casos em que você tem muitos argumentos semelhantes, especialmente se forem do mesmo tipo; nesse caso, prefiro usar argumentos nomeados ou crio uma classe personalizada se os argumentos pertencerem.
Estou surpreso que ninguém tenha mencionado o fato de que você pode misturar argumentos posicionais e de palavras-chave para fazer coisas sorrateiras como essa usando *args
e **kwargs
( deste site ):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
Isso permite que você use argumentos arbitrários de palavras-chave que podem ter chaves que você não deseja definir antecipadamente.
Eu estava procurando por um exemplo que tivesse kwargs padrão usando a anotação de tipo:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
exemplo:
>>> 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 suplementar / adicionar uma maneira de definir o valor padrão dos argumentos que não são atribuídos em palavras-chave ao chamar a função:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
chame isso por:
print(func())
print(func(my_word='love'))
você terá:
default_msg
love
leia mais sobre *args
e **kwargs
em python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3