Eu não entendo o exemplo a seguir, digamos que eu tenho essas funções:
# python likes
def save(filename, data, **kwargs):
fo = openX(filename, "w", **kwargs) # <- #1
fo.write(data)
fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
fo = openX(filename, "w", kwargs) # <- #2
fo.write(data)
fo.close()
def openX(filename, mode, **kwargs):
#doing something fancy and returning a file object
Por que o número 1 é a solução certa e o número 2 é o errado? **kwargs
é basicamente um ditado, então, se eu quiser passar o argumento para o openX, acho que o caminho correto seria sem **
e apenas dando o ditado. Mas o python obviamente não gosta do segundo e me diz que dei 3 em vez de 2 argumentos. Então, qual é a razão por trás disso?
**args
no código. Este é possivelmente o pior nome possível, como as pessoas vão confundi-lo com*args
Respostas:
No segundo exemplo, você fornece três argumentos: nome do arquivo, modo e um dicionário (
kwargs
). Mas o Python espera: 2 argumentos formais mais argumentos de palavras-chave.Ao prefixar o dicionário com '**', você descompacta o dicionário
kwargs
nos argumentos das palavras-chave.Um dicionário (tipo
dict
) é uma única variável que contém pares de valores-chave."Argumentos de palavras-chave" são parâmetros-método de valor-chave.
Qualquer dicionário pode ser descompactado para argumentos de palavras-chave, prefixando-o
**
durante a chamada de função.fonte
A
**
sintaxe diz ao Python para coletar argumentos de palavras-chave em um dicionário. Osave2
está passando como um argumento que não é de palavra-chave (um objeto de dicionário). OopenX
não está vendo nenhum argumento de palavra-chave para que**args
ele não seja usado. Em vez disso, está obtendo um terceiro argumento que não é de palavra-chave (o dicionário). Para corrigir isso, mude a definição daopenX
função.fonte
Expandindo a resposta da @gecco, a seguir está um exemplo que mostra a diferença:
Aqui você pode ver como a descompactação de um dicionário funciona e por que o envio de um dicionário real falha
fonte
Porque um dicionário é um valor único. Você precisará usar a expansão de palavras-chave se quiser passar como um grupo de argumentos de palavras-chave.
fonte
Para o número 2, args será apenas um parâmetro formal com valor dict, mas não um parâmetro de tipo de palavra-chave.
Se você deseja passar um parâmetro de tipo de palavra-chave para um argumento de palavra-chave, é necessário especificar ** antes do seu dicionário, o que significa ** args
verifique isso para obter mais detalhes sobre o uso de ** kw
http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
fonte