python examples - Uso de * args e ** kwargs





and python3 (10)


A sintaxe é o * e ** . Os nomes *args e **kwargs são apenas por convenção, mas não há necessidade de usá-los.

Você usaria *args quando não tiver certeza de quantos argumentos podem ser passados ​​para sua função, isto é, permite que você passe um número arbitrário de argumentos para sua função. Por exemplo:

>>> def print_everything(*args):
        for count, thing in enumerate(args):
...         print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage

Da mesma forma, **kwargs permite que você manipule argumentos nomeados que você não definiu previamente:

>>> def table_things(**kwargs):
...     for name, value in kwargs.items():
...         print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit

Você pode usá-los junto com argumentos nomeados também. Os argumentos explícitos obtêm os valores primeiro e depois todo o resto é passado para *args e **kwargs . Os argumentos nomeados vêm em primeiro lugar na lista. Por exemplo:

def table_things(titlestring, **kwargs)

Você também pode usar ambos na mesma definição de função, mas *args deve ocorrer antes de **kwargs .

Você também pode usar a sintaxe * e ** ao chamar uma função. Por exemplo:

>>> def print_three_things(a, b, c):
...     print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat

Como você pode ver, neste caso, pega a lista (ou tupla) dos itens e a descompacta. Por isso, combina-os com os argumentos da função. Claro, você poderia ter um * tanto na definição da função quanto na chamada de função.

Então eu tenho dificuldade com o conceito de *args e **kwargs .

Até agora eu aprendi que:

  • *args = lista de argumentos - como argumentos posicionais
  • **kwargs = dicionário - cujas chaves se tornam argumentos de palavra-chave separados e os valores se tornam valores desses argumentos.

Eu não entendo que tarefa de programação isso seria útil.

Talvez:

Eu acho que para inserir listas e dicionários como argumentos de uma função e ao mesmo tempo como um curinga, então eu posso passar qualquer argumento?

Existe um exemplo simples para explicar como *args e **kwargs são usados?

Também o tutorial que encontrei usou apenas o "*" e um nome de variável.

São *args e **kwargs apenas espaços reservados ou você usa exatamente *args e **kwargs no código?




* args e ** kwargs são recursos mágicos especiais do Python. Pense em uma função que poderia ter um número desconhecido de argumentos. Por exemplo, por qualquer motivo, você quer ter uma função que some um número desconhecido de números (e você não quer usar a função soma incorporada). Então você escreve esta função:

def sumFunction(*args):
  result = 0
  for x in args:
    result += x
  return result

e usá-lo como: sumFunction (3,4,6,3,6,8,9).

** kwargs tem uma função diferente. Com ** kwargs você pode dar argumentos arbitrários para uma função e você pode acessá-los como um dictonary.

def someFunction(**kwargs):
  if 'text' in kwargs:
    print kwargs['text']

Chamar someFunction (text = "foo") será impresso foo.




Um lugar onde o uso de *args e **kwargs é bastante útil é para subclassificação.

class Foo(object):
    def __init__(self, value1, value2):
        # do something with the values
        print value1, value2

class MyFoo(Foo):
    def __init__(self, *args, **kwargs):
        # do something else, don't care about the args
        print 'myfoo'
        super(MyFoo, self).__init__(*args, **kwargs)

Desta forma, você pode estender o comportamento da classe Foo, sem precisar saber muito sobre o Foo. Isso pode ser bastante conveniente se você estiver programando para uma API que pode mudar. MyFoo apenas passa todos os argumentos para a classe Foo.




Imagine que você tenha uma função, mas não quer restringir o número de parâmetros necessários. Exemplo:

>>> import operator
>>> def multiply(*args):
...  return reduce(operator.mul, args)

Então você usa essa função como:

>>> multiply(1,2,3)
6

or

>>> numbers = [1,2,3]
>>> multiply(*numbers)
6



Aqui está um dos meus lugares favoritos para usar a sintaxe ** como no exemplo final de Dave Webb:

mynum = 1000
mystr = 'Hello World!'
print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals())

Eu não tenho certeza se é muito rápido quando comparado a usar os nomes, mas é muito mais fácil digitar!




Aqui está um exemplo que usa três tipos diferentes de parâmetros.

def func(required_arg, *args, **kwargs):
    # required_arg is a positional-only parameter.
    print required_arg

    # args is a tuple of positional arguments,
    # because the parameter name has * prepended.
    if args: # If args is not empty.
        print args

    # kwargs is a dictionary of keyword arguments,
    # because the parameter name has ** prepended.
    if kwargs: # If kwargs is not empty.
        print kwargs

>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() takes at least 1 argument (0 given)

>>> func("required argument")
required argument

>>> func("required argument", 1, 2, '3')
required argument
(1, 2, '3')

>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
required argument
(1, 2, '3')
{'keyword2': 'foo', 'keyword1': 4}



Um caso em que * args e ** kwargs são úteis é quando se escrevem funções de invólucro (como decoradores) que precisam aceitar argumentos arbitrários para passar para a função que está sendo empacotada. Por exemplo, um decorador simples que imprime os argumentos e retorna o valor da função que está sendo empacotada:

def mydecorator( f ):
   @functools.wraps( f )
   def wrapper( *args, **kwargs ):
      print "Calling f", args, kwargs
      v = f( *args, **kwargs )
      print "f returned", v
      return v
   return wrapper



Esses parâmetros geralmente são usados ​​para funções de proxy, portanto, o proxy pode transmitir qualquer parâmetro de entrada para a função de destino.

def foo(bar=2, baz=5):
    print bar, baz

def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments
    print x
    foo(*args, **kwargs) # applies the "non-x" parameter to foo

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

Mas como esses parâmetros ocultam os nomes dos parâmetros reais, é melhor evitá-los.




Você pode dar uma olhada nos documentos python (docs.python.org no FAQ), mas mais especificamente para uma boa explicação sobre o misterioso miss args e o mister kwargs (cortesia do archive.org) (o original, link morto está aqui ).

Em poucas palavras, ambos são usados ​​quando parâmetros opcionais para uma função ou método são usados. Como Dave diz, * args é usado quando você não sabe quantos argumentos podem ser passados, e ** kwargs quando você quer manipular parâmetros especificados por nome e valor como em:

myfunction(myarg=1)



Você pode usar o **kwargs para permitir que suas funções recebam um número arbitrário de argumentos de palavras-chave ("kwargs" significa "argumentos de palavras-chave"):

>>> def print_keyword_args(**kwargs):
...     # kwargs is a dict of the keyword args passed to the function
...     for key, value in kwargs.iteritems():
...         print "%s = %s" % (key, value)
... 
>>> print_keyword_args(first_name="John", last_name="Doe")
first_name = John
last_name = Doe

Você também pode usar a sintaxe do **kwargs ao chamar funções construindo um dicionário de argumentos de palavras-chave e passando-os para a sua função:

>>> kwargs = {'first_name': 'Bobby', 'last_name': 'Smith'}
>>> print_keyword_args(**kwargs)
first_name = Bobby
last_name = Smith

O tutorial do Python contém uma boa explicação de como ele funciona, junto com alguns bons exemplos.

<- Atualizar ->

Para pessoas que usam o Python 3, em vez de iteritems (), use items ()







python args kwargs