Qual é o nome de ** em python?

59

Ao programar o Python, às vezes faço um **para fazer uma conversão. Entendo o que ele faz, mas quais estruturas de dados estou manipulando? A dicte qual é a outra? Um array? Existe um nome para o **operador?

Niklas Rosencrantz
fonte
3
operador exponencial?
Rook
12
Existem dois significados para **. Poder e "dicionário de argumentos de palavras-chave". Do que você está falando? A documentação possui as seguintes palavras: "Se o formulário" ** identificador "estiver presente, ele será inicializado para um novo dicionário que receba argumentos de palavras-chave em excesso, assumindo como padrão um novo dicionário vazio". Quais deles parecem relevantes para sua pergunta?
S.Lott
"Palavra-chave argumento dicionário" foi o que eu estou perguntando. Obrigado pelos comentários.
Niklas Rosencrantz

Respostas:

86

Não é um operador como tal, para que ele não realmente tem um nome, mas ela é definida como uma "regra sintática" . Por isso, deve ser chamado:

  • "o argumento da palavra-chave descompactando sintaxe"

Se você possui uma lista de argumentos, *argsela é chamada de "descompactação de argumento" , da mesma maneira que **kwargsé chamada de "descompactação de argumento de palavra-chave" .

Se você usá-lo no lado esquerdo de um =, como em a, *middle, end = my_tuple, diria "desembalar a tupla" .

No total, existem três tipos de argumentos (parâmetro único):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

O *argsargumento é chamado de "parâmetro posicional variável" e **kwargsé o "parâmetro de palavra-chave variável". Os argumentos somente de palavra-chave não podem ser fornecidos posicionalmente, porque um parâmetro posicional variável aceita todos os argumentos que você passa.

A maior parte disso pode ser encontrada nas PEPs 0362 e 3102 , bem como na seção Fluxo de Controle dos documentos. Note-se, porém, que o objeto PEP da assinatura da função é apenas um rascunho, e a terminologia pode ser apenas uma ideia de uma pessoa. Mas eles são bons termos de qualquer maneira. :)

Portanto, os argumentos *e **apenas descompactam suas respectivas estruturas de dados:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables são objetos que implementam o __iter__()método e mapeamentos são objetos que implementam keys()e __getitem__(). Qualquer objeto que suporte esse protocolo será entendido pelos construtores tuple()e dict(), portanto, eles podem ser usados ​​para descompactar argumentos.

Stefano Palazzo
fonte
3
Caso alguém esteja confuso, a def f(x, *xs, y=0): passsintaxe do Python 2. {5,6,7} não é válida, nem faz o def f(x, y=0, *xs):que você poderia esperar. AFAIK, a única maneira de alcançar o (obviamente) efeito pretendido é def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... O Python 3 lida com a sintaxe original conforme o esperado.
chbrown 14/09/13
11
Enquanto estamos nisso: a begin, *middle, end = (0, 1, 2, 3, 4, 5)sintaxe também não funciona no Python 2.x.
Stefano Palazzo
Esta resposta está incorreta no Python 3.5 e posterior. O PEP-448 especifica o operador ** como o operador de desempacotamento do dicionário. Veja python.org/dev/peps/pep-0448
devnul3
13

Eu não acho que tenha um nome. Nos documentos do Python, em "Descompactar listas de argumentos", é conhecido como "o **operador".

Não sei ao certo o que você quer dizer com "a outra" estrutura de dados. Quando você f(**kwargs)descompacta o dicionário kwargscomo uma sequência de pares de valores-chave. Não vejo que exista outra estrutura envolvida.

Copiarei o exemplo na documentação acima para maior clareza.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Veja também: O que significam * args e ** kwargs?

Kris Harper
fonte
Existem várias maneiras possíveis de um leitor pode interpretar f(**kwargs)...
Deer Hunter
3

Se você não souber ao certo como chamar um operador específico ou se ele não tiver nome, sempre poderá recorrer ao Waka Waka Bang Splat como uma referência para ajudá-lo a descobrir como chamá-lo. Nesse caso, **eu chamaria isso double-splat, embora haja alguns nomes alternativos para símbolos .

aculich
fonte