python Uso de * args e ** kwargs





5 Answers

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.

python args kwargs

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?




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!




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




Os nomes *args e **kwargs ou **kw são puramente por convenção. Torna mais fácil para nós lermos o código do outro

Um lugar é útil ao usar o módulo struct

struct.unpack() retorna uma tupla, enquanto struct.pack() usa um número variável de argumentos. Ao manipular dados, é conveniente poder passar uma tupla para struck.pack() por exemplo.

tuple_of_data = struct.unpack(format_str, data)
... manipulate the data
new_data = struct.pack(format_str, *tuple_of_data)

sem essa habilidade você seria forçado a escrever

new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)

o que também significa que se o format_str mudar e o tamanho da tupla for alterado, terei que voltar e editar essa linha realmente longa




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.






Related