Nas definições de método a seguir, o que o *
e **
faz param2
?
def foo(param1, *param2):
def bar(param1, **param2):
Nas definições de método a seguir, o que o *
e **
faz param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Para uma pergunta perguntando o que significa em chamadas de função (func(*[1,2])
), veja aqui . Para uma pergunta sobre como descompactar listas de argumentos, consulte aqui . Para uma pergunta perguntando o que*
significa em literais ([*[1, 2]]
), veja aqui .Respostas:
O
*args
e**kwargs
é um idioma comum para permitir que um número arbitrário de argumentos funcione, conforme descrito na seção mais sobre como definir funções na documentação do Python.O
*args
vai lhe dar todos os parâmetros de função como uma tupla :O
**kwargs
vai lhe dar todas argumentos chave , exceto para aqueles que corresponde a um parâmetro formal como um dicionário.Ambos os idiomas podem ser misturados com argumentos normais para permitir um conjunto de argumentos fixos e alguns variáveis:
Também é possível usar isso ao contrário:
Outro uso do
*l
idioma é descompactar listas de argumentos ao chamar uma função.No Python 3, é possível usar
*l
no lado esquerdo de uma atribuição ( descompactação iterável estendida ), apesar de fornecer uma lista em vez de uma tupla neste contexto:Além disso, o Python 3 adiciona uma nova semântica (consulte PEP 3102 ):
Essa função aceita apenas três argumentos posicionais e tudo o que se segue
*
só pode ser passado como argumento de palavra-chave.fonte
**kwargs
agora corresponde à ordem na qual os argumentos das palavras-chave foram passados para a função." - docs.python.org/3/whatsnew/3.6.html De fato, todos os ditados no CPython 3.6 lembram a ordem de inserção como um detalhe de implementação; isso se torna padrão no Python 3.7.got an unexpected keyword argument 'name'
Também é importante notar que você pode usar
*
e**
ao chamar funções também. Este é um atalho que permite passar vários argumentos para uma função diretamente usando uma lista / tupla ou um dicionário. Por exemplo, se você tiver a seguinte função:Você pode fazer coisas como:
Nota: As teclas
mydict
devem ser nomeadas exatamente como os parâmetros da funçãofoo
. Caso contrário, ele lançará umTypeError
:fonte
O único * significa que pode haver qualquer número de argumentos posicionais extras.
foo()
pode ser invocado comofoo(1,2,3,4,5)
. No corpo de foo (), param2 é uma sequência contendo 2-5.O duplo ** significa que pode haver qualquer número de parâmetros nomeados extras.
bar()
pode ser invocado comobar(1, a=2, b=3)
. No corpo de bar (), param2 é um dicionário que contém {'a': 2, 'b': 3}Com o seguinte código:
a saída é
fonte
foobar(param1, *param2, **param3)
seja necessário um exemplo adicional com para completar esta resposta.Eles permitem que funções sejam definidas para aceitar e que os usuários passem qualquer número de argumentos, posicional (
*
) e palavra-chave (**
).Definindo Funções
*args
permite qualquer número de argumentos posicionais opcionais (parâmetros), que serão atribuídos a uma tupla chamadaargs
.**kwargs
permite qualquer número de argumentos opcionais de palavra-chave (parâmetros), que estarão em um ditado chamadokwargs
.Você pode (e deve) escolher qualquer nome apropriado, mas se a intenção é que os argumentos sejam de semântica não específica
args
ekwargs
sejam nomes padrão.Expansão, passando qualquer número de argumentos
Você também pode usar
*args
e**kwargs
passar parâmetros de listas (ou qualquer iterável) e dictos (ou qualquer mapeamento), respectivamente.A função que recebe os parâmetros não precisa saber que eles estão sendo expandidos.
Por exemplo, o xrange do Python 2 não espera explicitamente
*args
, mas como ele usa 3 números inteiros como argumentos:Como outro exemplo, podemos usar a expansão dict em
str.format
:Novo no Python 3: Definindo funções com argumentos apenas de palavras-chave
Você pode ter argumentos apenas de palavras-chave depois de
*args
- por exemplo, aqui,kwarg2
deve ser fornecido como um argumento de palavras-chave - não em posição:Uso:
Além disso,
*
pode ser usado por si só para indicar que somente os argumentos de palavra-chave seguem, sem permitir argumentos posicionais ilimitados.Aqui,
kwarg2
novamente , deve haver um argumento de palavra-chave explicitamente nomeado:E não podemos mais aceitar argumentos posicionais ilimitados porque não temos
*args*
:Mais uma vez, de forma mais simples, aqui precisamos
kwarg
ser nomeados, não posicionalmente:Neste exemplo, vemos que, se tentarmos passar
kwarg
posicionalmente, obtemos um erro:Devemos passar explicitamente o
kwarg
parâmetro como um argumento de palavra-chave.Demonstrações compatíveis com Python 2
*args
(tipicamente dito "star-args") e**kwargs
(estrelas podem ser implícitas dizendo "kwargs", mas seja explícito com "starwar kwargs") são expressões comuns do Python para usar a notação*
e**
. Esses nomes de variáveis específicos não são necessários (por exemplo, você pode usar*foos
e**bars
), mas uma saída da convenção provavelmente enfurecerá seus colegas codificadores Python.Normalmente, usamos isso quando não sabemos o que nossa função receberá ou quantos argumentos podemos estar passando e, às vezes, mesmo ao nomear cada variável separadamente, fica muito confuso e redundante (mas este é um caso em que geralmente é explícito). melhor que implícito).
Exemplo 1
A função a seguir descreve como eles podem ser usados e demonstra comportamento. Observe que o
b
argumento nomeado será consumido pelo segundo argumento posicional antes:Podemos verificar a ajuda online da assinatura da função, com
help(foo)
, o que nos dizVamos chamar essa função com
foo(1, 2, 3, 4, e=5, f=6, g=7)
que imprime:
Exemplo 2
Também podemos chamá-lo usando outra função, na qual apenas fornecemos
a
:bar(100)
impressões:Exemplo 3: uso prático em decoradores
OK, então talvez ainda não estejamos vendo o utilitário. Imagine que você tenha várias funções com código redundante antes e / ou depois do código de diferenciação. As seguintes funções nomeadas são apenas pseudocódigo para fins ilustrativos.
Podemos ser capazes de lidar com isso de maneira diferente, mas certamente podemos extrair a redundância com um decorador; portanto, nosso exemplo abaixo demonstra como
*args
e**kwargs
pode ser muito útil:E agora todas as funções agrupadas podem ser escritas de maneira muito mais sucinta, como consideramos a redundância:
E, considerando o nosso código, o que
*args
e o**kwargs
que nos permite fazer, reduzimos as linhas de código, melhoramos a legibilidade e a capacidade de manutenção e temos únicos locais canônicos para a lógica do nosso programa. Se precisarmos alterar qualquer parte dessa estrutura, teremos um lugar para fazer cada alteração.fonte
Vamos primeiro entender o que são argumentos posicionais e argumentos de palavras-chave. Abaixo está um exemplo de definição de função com argumentos posicionais.
Portanto, esta é uma definição de função com argumentos posicionais. Você também pode chamá-lo com argumentos de palavra-chave / nomeados:
Agora vamos estudar um exemplo de definição de função com argumentos de palavra - chave :
Você também pode chamar essa função com argumentos posicionais:
Portanto, agora conhecemos as definições de função com argumentos posicionais e de palavras-chave.
Agora vamos estudar o operador '*' e o operador '**'.
Observe que esses operadores podem ser usados em 2 áreas:
a) chamada de função
b) definição de função
O uso do operador '*' e do operador '**' na chamada de função.
Vamos direto a um exemplo e depois discutimos.
Então lembre
quando o operador '*' ou '**' é usado em uma chamada de função -
O operador '*' descompacta a estrutura de dados, como uma lista ou tupla, nos argumentos necessários para a definição da função.
O operador '**' descompacta um dicionário nos argumentos necessários para a definição da função.
Agora vamos estudar o uso do operador '*' na definição de função . Exemplo:
Na definição da função, o operador '*' agrupa os argumentos recebidos em uma tupla.
Agora vamos ver um exemplo de '**' usado na definição de função:
Na definição da função O operador '**' agrupa os argumentos recebidos em um dicionário.
Então lembre:
Em uma chamada de função, o '*' descompacta a estrutura de dados da tupla ou da lista em argumentos posicionais ou de palavras-chave a serem recebidos pela definição da função.
Em uma chamada de função, o '**' descompacta a estrutura de dados do dicionário em argumentos posicionais ou de palavras-chave a serem recebidos pela definição da função.
Em uma definição de função, o '*' agrupa argumentos posicionais em uma tupla.
Em uma definição de função, o '**' agrupa os argumentos da palavra-chave em um dicionário.
fonte
Esta tabela é útil para usar
*
e**
na construção de funções e chamada de função :Isso realmente serve apenas para resumir a resposta de Lorin Hochstein, mas acho útil.
De maneira semelhante: os usos para os operadores estrela / splat foram expandidos no Python 3
fonte
*
e**
tem uso especial na lista de argumentos da função.*
implica que o argumento é uma lista e**
implica que o argumento é um dicionário. Isso permite que as funções recebam um número arbitrário de argumentosfonte
Para aqueles de vocês que aprendem por exemplos!
*
é fornecer a capacidade de definir uma função que pode receber um número arbitrário de argumentos fornecidos como uma lista (por exemplof(*myList)
).**
é fornecer a capacidade de alimentar os argumentos de uma função, fornecendo um dicionário (por exemplof(**{'x' : 1, 'y' : 2})
).Vamos mostrar isso definindo uma função que leva duas variáveis normais
x
,y
e pode aceitar mais argumentos comomyArgs
, e pode aceitar ainda mais argumentos comomyKW
. Mais tarde, mostraremos como alimentary
usandomyArgDict
.Ressalvas
**
está reservado exclusivamente para dicionários.**
deve vir depois*
, sempre.fonte
Na documentação do Python:
fonte
*
significa receber argumentos variáveis como tupla**
significa receber argumentos variáveis como dicionárioUsado como o seguinte:
1) solteiro *
Resultado:
2) Agora
**
Resultado:
fonte
Eu quero dar um exemplo que outros não mencionaram
* também pode desembalar um gerador
Um exemplo do documento Python3
unzip_x será [1, 2, 3], unzip_y será [4, 5, 6]
O zip () recebe vários argumentos irretáveis e retorna um gerador.
fonte
Em Python 3.5, você também pode usar essa sintaxe em
list
,dict
,tuple
eset
exibe (também às vezes chamados de literais). Consulte PEP 488: Generalizações adicionais de desempacotamento .Ele também permite que vários iteráveis sejam descompactados em uma única chamada de função.
(Obrigado a mgilson pelo link do PEP.)
fonte
Além das chamadas de função, * args e ** kwargs são úteis nas hierarquias de classes e também evitam a necessidade de escrever o
__init__
método no Python. Uso semelhante pode ser visto em estruturas como o código Django.Por exemplo,
Uma subclasse pode então ser
A subclasse será instanciada como
Além disso, uma subclasse com um novo atributo que faça sentido apenas para essa instância da subclasse pode chamar a classe Base
__init__
para descarregar a configuração de atributos. Isso é feito através de * args e ** kwargs. kwargs usado principalmente para que o código seja legível usando argumentos nomeados. Por exemplo,que pode ser instatado como
O código completo está aqui
fonte
Com base na resposta de nickd ...
Resultado:
Basicamente, qualquer número de argumentos posicionais pode usar * args e qualquer argumento nomeado (ou kwargs, também conhecido como argumento de palavra-chave) pode usar ** kwargs.
fonte
*args
e**kwargs
: permitem passar um número variável de argumentos para uma função.*args
: é usado para enviar uma lista de argumentos de comprimento variável sem palavra-chave para a função:Vai produzir:
**kwargs*
**kwargs
permite que você passe o comprimento variável de argumentos com palavras-chave para uma função. Você deve usar**kwargs
se desejar manipular argumentos nomeados em uma função.Vai produzir:
fonte
Este exemplo ajudaria você a se lembrar
*args
,**kwargs
e mesmosuper
e herança no Python de uma só vez.fonte
Um bom exemplo de uso de ambos em uma função é:
fonte
TL; DR
Abaixo estão 6 casos de uso diferentes para
*
e**
na programação python:*args
:def foo(*args): pass
, aquifoo
aceita qualquer número de argumentos posicionais, ou seja, as seguintes chamadas são válidosfoo(1)
,foo(1, 'bar')
**kwargs
:def foo(**kwargs): pass
, aqui 'foo' aceita qualquer número de argumentos de palavra-chave, ou seja, as seguintes chamadas são válidosfoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:def foo(*args, **kwargs): pass
, aquifoo
aceita qualquer número de argumentos posicionais e, ou seja, as seguintes chamadas são válidosfoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:def foo(pos1, pos2, *, kwarg1): pass
, aqui*
significa que foo só aceitam argumentos nomeados após pos2, portanto,foo(1, 2, 3)
levanta TypeError masfoo(1, 2, kwarg1=3)
é ok.*_
(Nota: esta é apenas uma convenção):def foo(bar, baz, *_): pass
significa (por convenção)foo
apenas usabar
ebaz
argumentos em seu funcionamento e ignorará outros.\**_
(Nota: esta é apenas uma convenção):def foo(bar, baz, **_): pass
significa (por convenção)foo
apenas usabar
ebaz
argumentos em seu funcionamento e ignorará outros.BÔNUS: A partir do python 3.8 em diante, pode-se usar
/
na definição de funções para aplicar apenas parâmetros posicionais. No exemplo a seguir, os parâmetros aeb são apenas posicionais , enquanto c ou d podem ser posicionais ou palavra-chave, e e ou f devem ser palavras-chave:fonte
TL; DR
Empacota os argumentos passados para a função dentro
list
edict
respectivamente dentro do corpo da função. Quando você define uma assinatura de função como esta:pode ser chamado com qualquer número de argumentos e argumentos de palavras-chave. Os argumentos que não são de palavra-chave são compactados em uma lista chamada
args
dentro do corpo da função e os argumentos de palavra-chave são compactados em um ditado chamadokwds
dentro do corpo da função.agora dentro do corpo da função, quando a função é chamada, há duas variáveis locais,
args
que é uma lista com valor["this", "is a list of", "non-keyword", "arguments"]
ekwds
que é umdict
valor com{"keyword" : "ligma", "options" : [1,2,3]}
Isso também funciona ao contrário, ou seja, do lado do chamador. por exemplo, se você tiver uma função definida como:
você pode chamá-lo descompactando iterables ou mapeamentos existentes no escopo da chamada:
fonte
Contexto
**
Use com formatação de string
Além das respostas neste tópico, aqui está outro detalhe que não foi mencionado em nenhum outro lugar. Isso se expande no resposta de Brad Solomon
Descompactar
**
também é útil ao usar pythonstr.format
.Isso é um pouco semelhante ao que você pode fazer com o python
f-strings
f-string mas com a sobrecarga adicional de declarar um dict para conter as variáveis (a string f não exige um dict).Exemplo rápido
fonte
def foo(param1, *param2):
é um método que pode aceitar um número arbitrário de valores para*param2
,def bar(param1, **param2):
é um método que pode aceitar um número arbitrário de valores com chaves para*param2
param1
é um parâmetro simples.Por exemplo, a sintaxe para implementar varargs em Java da seguinte maneira:
fonte