Pergunta

Como são os "argumentos nomeados" diferente dos argumentos regulares? não pode todos os argumentos ser passados ??como name=value em vez de usar a sintaxe posicional?

Foi útil?

Solução

existem dois conceitos relacionados, ambos chamados "argumentos nomeados".

No lado chamando, que é o que outros comentadores ter mencionado, você tem a capacidade de especificar alguns argumentos da função pelo nome. Você tem que mencioná-los depois de todos os argumentos, sem nomes (argumentos posicionais), e deve haver valores padrão para todos os parâmetros que não foram mencionados em tudo.

O outro conceito é no lado da definição de função: Você pode definir uma função que usa parâmetros pelo nome - e você não tem sequer a especificar o que esses nomes são. Estes são argumentos chave puros, e não podem ser passados ??posicionalmente. A sintaxe é

def my_function(arg1, arg2, **kwargs)

Qualquer argumento que você passa 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, como este:

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

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

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

Outras dicas

Há uma característica último idioma onde a distinção é importante. Considere a seguinte função:

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

O argumento *positional irá armazenar todos os argumentos posicionais passados ??para foo(), sem limite de quantos você pode fornecer.

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

O argumento **keywords irá armazenar quaisquer argumentos 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 são raramente usados, mas, ocasionalmente, eles são muito úteis, e é importante saber quais argumentos são posicionais ou palavras-chave.

Usando argumentos de palavra-chave é a mesma coisa como argumentos normais, exceto ordem não importa. Por exemplo as duas funções chamadas a seguir são os mesmos:

def foo(bar, baz):
    pass

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

posicional Argumentos

Eles não têm palavras-chave antes deles. A ordem é importante!

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

Argumentos palavra-chave

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 negligência para inserir as palavras-chave, então a ordem será então a matéria!

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

Existem duas formas de valores de argumento atribuir a parâmetros da função, tanto são utilizados.

  1. Por Posição. argumentos posicionais não tem palavras-chave e são atribuídos pela primeira vez.

  2. Por palavra-chave. argumentos de palavra-chave tem palavras-chave e são atribuídos segundo, depois de argumentos posicionais.

Note que você tem a opção de usar argumentos posicionais.

Se você não use argumentos posicionais, então - Sim. - tudo você escreveu acaba por 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 fizer essa escolha e usar argumentos posicionais.

Estou surpreso que ninguém parece ter apontou que se 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
>>> 

Usando Python 3 você pode ter ambos necessários e não necessários palavra-chave argumentos :

Opcional : (valor padrão definido para '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 '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 ao lado do outro, especialmente quando do mesmo tipo, nesse caso, eu prefiro usar argumentos nomeados ou eu criar uma classe personalizada se argumentos pertencem juntos.

Estou surpreso que ninguém tenha mencionado o fato de que você pode misturar argumentos posicionais e de fazer as coisas sorrateiras como esta usando *args e **kwargs ( a partir 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ê usar argumentos nomeados arbitrárias que podem ter chaves que você não quer para definir antecipadamente.

Eu estava procurando por um exemplo que tinha kwargs fábrica utilizando tipo de anotação:

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 {}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top