¿Qué significa asterisco * en Python? [duplicar]

Resuelto Martin08 asked hace 15 años • 5 respuestas

¿Tiene * un significado especial en Python como lo tiene en C? Vi una función como esta en el libro de cocina de Python:

def get(self, *a, **kw)

¿Podría explicármelo o indicarme dónde puedo encontrar una respuesta? (Google interpreta el * como comodín y, por lo tanto, no puedo encontrar una respuesta satisfactoria).

Martin08 avatar Dec 30 '08 23:12 Martin08
Aceptado

Consulte Definiciones de funciones en la Referencia del lenguaje.

Si el formulario *identifierestá presente, se inicializa en una tupla que recibe cualquier parámetro posicional sobrante y, por defecto, la tupla vacía. Si el formulario **identifierestá presente, se inicializa en un nuevo diccionario que recibe cualquier argumento de palabra clave sobrante y, de forma predeterminada, es un nuevo diccionario vacío.

Consulte también Llamadas a funciones .

Suponiendo que uno sabe qué son los argumentos posicionales y de palabras clave, aquí hay algunos ejemplos:

Ejemplo 1:

# Excess keyword argument (python 3) example:
def foo(a, b, c, **args):
    print("a = %s" % (a,))
    print("b = %s" % (b,))
    print("c = %s" % (c,))
    print(args)
    
foo(a="testa", d="excess", c="testc", b="testb", k="another_excess")

Como puede ver en el ejemplo anterior, solo tenemos parámetros a, b, cen la firma de la foofunción. Como dy kno están presentes, se colocan en el diccionario de argumentos. La salida del programa es:

a = testa
b = testb
c = testc
{'k': 'another_excess', 'd': 'excess'}

Ejemplo 2:

# Excess positional argument (python 3) example:
def foo(a, b, c, *args):
    print("a = %s" % (a,))
    print("b = %s" % (b,))
    print("c = %s" % (c,))
    print(args)
        
foo("testa", "testb", "testc", "excess", "another_excess")

Aquí, dado que estamos probando argumentos posicionales, los que sobran tienen que estar al final y *argsempaquetarse en una tupla, por lo que el resultado de este programa es:

a = testa
b = testb
c = testc
('excess', 'another_excess')

También puedes descomprimir un diccionario o una tupla en argumentos de una función:

def foo(a,b,c,**args):
    print("a=%s" % (a,))
    print("b=%s" % (b,))
    print("c=%s" % (c,))
    print("args=%s" % (args,))

argdict = dict(a="testa", b="testb", c="testc", excessarg="string")
foo(**argdict)

Huellas dactilares:

a=testa
b=testb
c=testc
args={'excessarg': 'string'}

Y

def foo(a,b,c,*args):
    print("a=%s" % (a,))
    print("b=%s" % (b,))
    print("c=%s" % (c,))
    print("args=%s" % (args,))

argtuple = ("testa","testb","testc","excess")
foo(*argtuple)

Huellas dactilares:

a=testa
b=testb
c=testc
args=('excess',)
S.Lott avatar Dec 30 '2008 16:12 S.Lott

Solo tengo una cosa que agregar que no quedó clara en las otras respuestas (en aras de la integridad).

También puedes usar las estrellas al llamar a la función. Por ejemplo, digamos que tiene un código como este:

>>> def foo(*args):
...     print(args)
...
>>> l = [1,2,3,4,5]

Puedes pasar la lista l a foo así...

>>> foo(*l)
(1, 2, 3, 4, 5)

Puedes hacer lo mismo con los diccionarios...

>>> def foo(**argd):
...     print(argd)
...
>>> d = {'a' : 'b', 'c' : 'd'}
>>> foo(**d)
{'a': 'b', 'c': 'd'}
Jason Baker avatar Dec 30 '2008 16:12 Jason Baker

Todas las respuestas anteriores fueron perfectamente claras y completas, pero solo para que conste, me gustaría confirmar que el significado de * y ** en Python no tiene absolutamente ninguna similitud con el significado de operadores de apariencia similar en C.

Se denominan operadores de desempaquetado de argumentos y de desempaquetado de argumentos de palabras clave.

Salim Fadhley avatar Jan 02 '2009 10:01 Salim Fadhley

Una sola estrella significa que la variable 'a' será una tupla de parámetros adicionales que se proporcionaron a la función. La estrella doble significa que la variable 'kw' será un diccionario de tamaño variable de parámetros adicionales que se proporcionaron con palabras clave.

Aunque el comportamiento real está especificado, a veces puede resultar muy poco intuitivo. Escribir algunas funciones de muestra y llamarlas con varios estilos de parámetros puede ayudarle a comprender qué está permitido y cuáles son los resultados.

def f0(a)
def f1(*a)
def f2(**a)
def f3(*a, **b)
etc...
HUAGHAGUAH avatar Dec 30 '2008 16:12 HUAGHAGUAH

Encuentro * útil al escribir una función que toma otra función de devolución de llamada como parámetro:

def some_function(parm1, parm2, callback, *callback_args):
    a = 1
    b = 2
    ...
    callback(a, b, *callback_args)
    ...

De esa manera, las personas que llaman pueden pasar parámetros adicionales arbitrarios que se pasarán a su función de devolución de llamada. Lo bueno es que la función de devolución de llamada puede utilizar parámetros de función normales. Es decir, no es necesario utilizar la sintaxis * en absoluto. He aquí un ejemplo:

def my_callback_function(a, b, x, y, z):
    ...

x = 5
y = 6
z = 7

some_function('parm1', 'parm2', my_callback_function, x, y, z)

Por supuesto, los cierres proporcionan otra forma de hacer lo mismo sin necesidad de pasar x, y, z a través de some_function() y my_callback_function().

Clint Miller avatar Dec 30 '2008 17:12 Clint Miller