¿Cuál es el nombre de ** en python?

59

Al programar Python, a veces hago un **para hacer una conversión. Entiendo lo que hace, pero ¿qué estructuras de datos estoy manipulando? A dicty cual es el otro? Un array? ¿Hay un nombre para el **operador?

Niklas Rosencrantz
fuente
3
operador exponencial?
Torre el
12
Hay dos significados para **. Poder y "diccionario de argumentos de palabras clave". De que estas hablando La documentación tiene estas palabras: "Si está presente el formulario" ** identificador ", se inicializa en un nuevo diccionario que recibe cualquier argumento de palabras clave en exceso, por defecto en un nuevo diccionario vacío". ¿Cuál de ellos parece relevante para tu pregunta?
S.Lott
"diccionario de argumentos de palabras clave" fue el que estoy preguntando. Gracias por los comentarios.
Niklas Rosencrantz

Respuestas:

86

No es un operador como tal, por lo que realmente no tiene un nombre, pero se define como una "regla sintáctica" . Entonces debería llamarse:

  • "la sintaxis de desempaquetado del argumento de palabra clave"

Si tiene una lista de argumentos, *argsse llama "desempaquetado de argumentos" , de la misma manera **kwargsse llama "desempaquetado de argumentos de palabras clave" .

Si lo usa en el lado izquierdo de un =, como en a, *middle, end = my_tuple, diría "desempaquetado de tuplas" .

En total, hay tres 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

El *argsargumento se denomina "parámetro de posición variable" y **kwargses el "parámetro de palabra clave variable". Los argumentos de solo palabras clave no se pueden dar posicionalmente, porque un parámetro posicional variable tomará todos los argumentos que pase.

La mayor parte de esto se puede encontrar en las PEP 0362 y 3102 , así como en la sección Flujo de control de los documentos. Sin embargo, debe tenerse en cuenta que el objeto de firma de función PEP es solo un borrador, y la terminología podría ser idea de una sola persona. Pero son buenos términos de todos modos. :)

Entonces, los argumentos *y **simplemente descomprimen sus respectivas estructuras de datos:

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]: los Iterables son objetos que implementan el __iter__()método y las asignaciones son objetos que implementan keys()y __getitem__(). Cualquier objeto que admita este protocolo será entendido por los constructores tuple()y dict(), por lo tanto, puede usarse para desempaquetar argumentos.

Stefano Palazzo
fuente
3
En caso de que alguien más esté confundido, def f(x, *xs, y=0): passno es válida la sintaxis de Python 2. {5,6,7}, ni hace def f(x, y=0, *xs):lo que podría esperar. AFAIK, la única forma de lograr el efecto (obviamente) deseado es def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 maneja la sintaxis original como se esperaba.
chbrown
1
Mientras estamos en eso: la begin, *middle, end = (0, 1, 2, 3, 4, 5)sintaxis tampoco funciona en Python 2.x.
Stefano Palazzo
Esta respuesta es incorrecta en Python 3.5 y versiones posteriores. PEP-448 especifica el operador ** como el operador de desempaquetado del diccionario. Ver python.org/dev/peps/pep-0448
devnul3
13

No creo que tenga nombre. En los documentos de Python en "Desempaquetado de listas de argumentos", simplemente se conoce como "el **operador".

No estoy seguro de lo que quiere decir con "la otra" estructura de datos. Cuando lo hace f(**kwargs), desempaqueta el diccionario kwargscomo una secuencia de pares clave-valor. No veo que haya otra estructura involucrada.

Copiaré el ejemplo en la documentación anterior para mayor claridad.

>>> 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 !

Ver también: ¿Qué significa * args y ** kwargs?

Kris Harper
fuente
Hay varias formas posibles en que un lector puede interpretar f(**kwargs)...
Deer Hunter