En las siguientes definiciones de métodos, lo que hace el *
y **
hacer por param2
?
def foo(param1, *param2):
def bar(param1, **param2):
En las siguientes definiciones de métodos, lo que hace el *
y **
hacer por param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Para una pregunta sobre qué significa en llamadas a funciones (func(*[1,2])
), consulte aquí . Para una pregunta sobre cómo desempaquetar listas de argumentos, vea aquí . Para una pregunta que pregunta qué*
significa en literales ([*[1, 2]]
) ver aquí .Respuestas:
El
*args
y**kwargs
es un idioma común para permitir un número arbitrario de argumentos para funciones como se describe en la sección más sobre la definición de funciones en la documentación de Python.El
*args
le dará todos los parámetros de la función como una tupla :Le
**kwargs
dará todos los argumentos de palabras clave, excepto los correspondientes a un parámetro formal como diccionario.Ambos modismos pueden mezclarse con argumentos normales para permitir un conjunto de argumentos fijos y algunos variables:
También es posible usar esto al revés:
Otro uso del
*l
idioma es desempaquetar listas de argumentos cuando se llama a una función.En Python 3 es posible usarlo
*l
en el lado izquierdo de una tarea ( Desembalaje extendido iterable ), aunque en este contexto proporciona una lista en lugar de una tupla:También Python 3 agrega nueva semántica (consulte PEP 3102 ):
Dicha función acepta solo 3 argumentos posicionales, y todo lo que sigue
*
solo puede pasarse como argumentos de palabras clave.fuente
**kwargs
ahora corresponde al orden en que los argumentos de palabras clave se pasaron a la función". - docs.python.org/3/whatsnew/3.6.html De hecho, todos los dictados en CPython 3.6 recordarán el orden de inserción como un detalle de implementación, esto se convierte en estándar en Python 3.7.got an unexpected keyword argument 'name'
También vale la pena señalar que puede usar
*
y**
al llamar funciones también. Este es un acceso directo que le permite pasar múltiples argumentos a una función directamente usando una lista / tupla o un diccionario. Por ejemplo, si tiene la siguiente función:Puedes hacer cosas como:
Nota: Las teclas en
mydict
deben nombrarse exactamente como los parámetros de la funciónfoo
. De lo contrario, arrojará unTypeError
:fuente
El * simple significa que puede haber cualquier número de argumentos posicionales adicionales.
foo()
se puede invocar comofoo(1,2,3,4,5)
. En el cuerpo de foo () param2 es una secuencia que contiene 2-5.El doble ** significa que puede haber cualquier número de parámetros con nombre adicionales.
bar()
se puede invocar comobar(1, a=2, b=3)
. En el cuerpo de bar () param2 hay un diccionario que contiene {'a': 2, 'b': 3}Con el siguiente código:
la salida es
fuente
foobar(param1, *param2, **param3)
se necesite un ejemplo adicional con para completar esta respuesta.Permiten que las funciones se definan para aceptar y que los usuarios pasen cualquier número de argumentos, posicionales (
*
) y palabras clave (**
).Definiendo funciones
*args
permite cualquier número de argumentos posicionales opcionales (parámetros), que se asignarán a una tupla llamadaargs
.**kwargs
permite cualquier número de argumentos de palabra clave opcionales (parámetros), que estarán en un dict con nombrekwargs
.Puede (y debe) elegir cualquier nombre apropiado, pero si la intención es que los argumentos sean de semántica no específica
args
y quekwargs
sean nombres estándar.Expansión, pasando cualquier número de argumentos
También puede usar
*args
y**kwargs
pasar parámetros de listas (o cualquier iterable) y dictados (o cualquier mapeo), respectivamente.La función que recibe los parámetros no tiene que saber que se están expandiendo.
Por ejemplo, xrange de Python 2 no espera explícitamente
*args
, pero dado que toma 3 enteros como argumentos:Como otro ejemplo, podemos usar la expansión dict en
str.format
:Nuevo en Python 3: definición de funciones con argumentos de solo palabras clave
Puede tener argumentos de solo palabras clave después de
*args
, por ejemplo, aquí,kwarg2
debe darse como argumento de palabras clave, no posicionalmente:Uso:
Además,
*
se puede usar solo para indicar que siguen los argumentos de palabras clave, sin permitir argumentos posicionales ilimitados.Aquí,
kwarg2
nuevamente debe haber un argumento de palabra clave explícitamente nombrado:Y ya no podemos aceptar argumentos posicionales ilimitados porque no tenemos
*args*
:De nuevo, más simplemente, aquí necesitamos
kwarg
que se nos dé por nombre, no por posición:En este ejemplo, vemos que si intentamos pasar
kwarg
posicionalmente, obtenemos un error:Debemos pasar explícitamente el
kwarg
parámetro como argumento de palabra clave.Demos compatibles con Python 2
*args
(normalmente se dice "star-args") y**kwargs
(las estrellas pueden estar implícitas diciendo "kwargs", pero sea explícito con "double-star kwargs") son expresiones idiomáticas comunes de Python para usar la notación*
y**
. Estos nombres de variables específicos no son obligatorios (por ejemplo, podría usar*foos
y**bars
), pero es probable que una desviación de la convención enfurezca a sus compañeros codificadores de Python.Por lo general, los usamos cuando no sabemos qué va a recibir nuestra función o cuántos argumentos podemos estar pasando, y a veces incluso cuando nombrar cada variable por separado se volvería muy desordenada y redundante (pero este es un caso donde generalmente es explícito mejor que implícito).
Ejemplo 1
La siguiente función describe cómo se pueden usar y demuestra el comportamiento. Tenga en cuenta que el
b
argumento nombrado será consumido por el segundo argumento posicional antes:Podemos consultar la ayuda en línea para la firma de la función, con
help(foo)
, que nos diceLlamemos a esta función con
foo(1, 2, 3, 4, e=5, f=6, g=7)
que imprime:
Ejemplo 2
También podemos llamarlo usando otra función, en la que solo proporcionamos
a
:bar(100)
huellas dactilares:Ejemplo 3: uso práctico en decoradores
Bien, quizás aún no estemos viendo la utilidad. Imagine que tiene varias funciones con código redundante antes y / o después del código diferenciador. Las siguientes funciones nombradas son solo pseudocódigo con fines ilustrativos.
Es posible que podamos manejar esto de manera diferente, pero ciertamente podemos extraer la redundancia con un decorador, por lo que nuestro siguiente ejemplo demuestra cómo
*args
y**kwargs
puede ser muy útil:Y ahora cada función envuelta se puede escribir de manera mucho más sucinta, ya que tenemos en cuenta la redundancia:
Y por factorización de nuestro código, el cual
*args
, y**kwargs
nos permite hacer, podemos reducir líneas de código, mejorar la legibilidad y facilidad de mantenimiento, y tienen lugares únicos canónicas para la lógica en nuestro programa. Si necesitamos cambiar alguna parte de esta estructura, tenemos un lugar en el que hacer cada cambio.fuente
Primero, comprendamos qué son los argumentos posicionales y los argumentos de palabras clave. A continuación se muestra un ejemplo de definición de función con argumentos posicionales.
Entonces esta es una definición de función con argumentos posicionales. También puede llamarlo con palabras clave / argumentos nombrados:
Ahora estudiemos un ejemplo de definición de función con argumentos de palabras clave :
También puede llamar a esta función con argumentos posicionales:
Así que ahora sabemos definiciones de funciones con argumentos posicionales y de palabras clave.
Ahora estudiemos el operador '*' y el operador '**'.
Tenga en cuenta que estos operadores se pueden utilizar en 2 áreas:
a) llamada de función
b) definición de función
El uso del operador '*' y el operador '**' en la llamada a la función.
Vayamos directamente a un ejemplo y luego discutamos.
Así que recuerda
cuando el operador '*' o '**' se usa en una llamada a función -
El operador '*' desempaqueta la estructura de datos como una lista o tupla en argumentos necesarios para la definición de la función.
El operador '**' desempaqueta un diccionario en argumentos necesarios para la definición de la función.
Ahora estudiemos el uso del operador '*' en la definición de funciones . Ejemplo:
En la definición de la función, el operador '*' empaqueta los argumentos recibidos en una tupla.
Ahora veamos un ejemplo de '**' usado en la definición de función:
En la definición de la función El operador '**' empaqueta los argumentos recibidos en un diccionario.
Así que recuerda:
En una llamada a función, el '*' descomprime la estructura de datos de tupla o lista en argumentos posicionales o de palabras clave que se recibirán por definición de función.
En una llamada a función, el '**' descomprime la estructura de datos del diccionario en argumentos posicionales o de palabras clave que se recibirán por definición de función.
En una definición de función, el '*' agrupa argumentos posicionales en una tupla.
En una definición de función, '**' incluye argumentos de palabras clave en un diccionario.
fuente
Esta tabla es útil para usar
*
y**
en la construcción de funciones y llamadas a funciones :Esto realmente sirve para resumir la respuesta de Lorin Hochstein, pero me parece útil.
Relacionado: los usos para los operadores estrella / splat se han ampliado en Python 3
fuente
*
y**
tiene un uso especial en la lista de argumentos de la función.*
implica que el argumento es una lista e**
implica que el argumento es un diccionario. Esto permite que las funciones tomen un número arbitrario de argumentosfuente
¡Para aquellos de ustedes que aprenden con ejemplos!
*
es darle la capacidad de definir una función que puede tomar un número arbitrario de argumentos proporcionados como una lista (por ejemplof(*myList)
).**
es darle la capacidad de alimentar los argumentos de una función proporcionando un diccionario (por ejemplof(**{'x' : 1, 'y' : 2})
).Vamos a mostrar esto definiendo una función que toma dos variables normales
x
,y
y puede aceptar más argumentosmyArgs
, y puede aceptar aún más argumentosmyKW
. Más adelante, mostraremos cómo alimentary
usandomyArgDict
.Advertencias
**
está reservado exclusivamente para diccionarios.**
debe venir después*
, siempre.fuente
De la documentación de Python:
fuente
*
significa recibir argumentos variables como tupla**
significa recibir argumentos variables como diccionarioUsado de la siguiente manera:
1) soltero *
Salida:
2) ahora
**
Salida:
fuente
Quiero dar un ejemplo que otros no hayan mencionado
* también puede desempaquetar un generador
Un ejemplo del documento Python3
unzip_x será [1, 2, 3], unzip_y será [4, 5, 6]
El zip () recibe múltiples argumentos irritables y devuelve un generador.
fuente
En Python 3.5, también se puede utilizar esta sintaxis en
list
,dict
,tuple
, yset
muestra (también llamado a veces literales). Ver PEP 488: Generalizaciones adicionales de desempaque .También permite desempaquetar múltiples iterables en una sola llamada de función.
(Gracias a mgilson por el enlace PEP).
fuente
Además de las llamadas a funciones, * args y ** kwargs son útiles en las jerarquías de clases y también evitan tener que escribir el
__init__
método en Python. Se puede ver un uso similar en marcos como el código Django.Por ejemplo,
Una subclase puede ser
La subclase se instanciará como
Además, una subclase con un nuevo atributo que solo tiene sentido para esa instancia de subclase puede llamar a la clase Base
__init__
para descargar la configuración de atributos. Esto se hace a través de * args y ** kwargs. kwargs se usa principalmente para que el código sea legible utilizando argumentos con nombre. Por ejemplo,que se puede instaurar como
El código completo está aquí.
fuente
Sobre la base de la respuesta de Nickd ...
Salida:
Básicamente, cualquier número de argumentos posicionales puede usar * args y cualquier argumento con nombre (o kwargs, también conocido como argumentos de palabras clave) puede usar ** kwargs.
fuente
*args
y**kwargs
: le permite pasar un número variable de argumentos a una función.*args
: se utiliza para enviar una lista de argumentos de longitud variable sin palabras clave a la función:Producirá:
**kwargs*
**kwargs
le permite pasar una longitud variable de argumentos con clave a una función. Debe usarlo**kwargs
si desea manejar argumentos con nombre en una función.Producirá:
fuente
Este ejemplo lo ayudaría a recordar
*args
,**kwargs
e incluso asuper
heredar en Python a la vez.fuente
Un buen ejemplo del uso de ambos en una función es:
fuente
TL; DR
A continuación se presentan 6 casos de uso diferentes para
*
y**
en la programación de Python:*args
:,def foo(*args): pass
aquífoo
acepta cualquier número de argumentos posicionales, es decir, las siguientes llamadas son válidasfoo(1)
,foo(1, 'bar')
**kwargs
:,def foo(**kwargs): pass
aquí 'foo' acepta cualquier número de argumentos de palabras clave, es decir, las siguientes llamadas son válidasfoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:,def foo(*args, **kwargs): pass
aquífoo
acepta cualquier número de argumentos posicionales y de palabras clave, es decir, las siguientes llamadas son válidasfoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:,def foo(pos1, pos2, *, kwarg1): pass
aquí*
significa que foo solo acepta argumentos de palabras clave después de pos2, por lo tanto,foo(1, 2, 3)
genera TypeError perofoo(1, 2, kwarg1=3)
está bien.*_
(Nota: esto es solo una convención):def foo(bar, baz, *_): pass
significa (por convención)foo
solo usabar
ybaz
argumentos en su funcionamiento e ignorará a los demás.\**_
(Nota: esto es solo una convención):def foo(bar, baz, **_): pass
significa (por convención)foo
solo usabar
ybaz
argumentos en su funcionamiento e ignorará a los demás.BONIFICACIÓN: desde Python 3.8 en adelante, se puede usar
/
en la definición de funciones para imponer parámetros solo posicionales. En el siguiente ejemplo, los parámetros a y b son solo posicionales , mientras que c o d pueden ser posicionales o palabras clave, y se requiere que eof sean palabras clave:fuente
TL; DR
Empaqueta argumentos pasados a la función dentro
list
ydict
respectivamente dentro del cuerpo de la función. Cuando define una firma de función como esta:Se puede llamar con cualquier número de argumentos y argumentos de palabras clave. Los argumentos que no son palabras clave se empaquetan en una lista llamada
args
dentro del cuerpo de la función y los argumentos de las palabras clave se empaquetan en un dict llamadokwds
dentro del cuerpo de la función.ahora dentro del cuerpo de la función, cuando se llama a la función, hay dos variables locales,
args
que es una lista que tiene valor["this", "is a list of", "non-keyword", "arguments"]
ykwds
que es undict
valor que tiene{"keyword" : "ligma", "options" : [1,2,3]}
Esto también funciona a la inversa, es decir, desde el lado de la persona que llama. por ejemplo si tiene una función definida como:
puede llamarlo desempacando iterables o asignaciones que tenga en el alcance de la llamada:
fuente
Contexto
**
Usar con formato de cadena
Además de las respuestas en este hilo, aquí hay otro detalle que no se mencionó en otra parte. Esto amplía la respuesta de Brad Solomon
Desempacar con
**
también es útil cuando se usa pythonstr.format
.Esto es algo similar a lo que puede hacer con python
f-strings
f-string pero con la sobrecarga adicional de declarar un dict para contener las variables (f-string no requiere un dict).Ejemplo rapido
fuente
def foo(param1, *param2):
es un método que puede aceptar un número arbitrario de valores para*param2
,def bar(param1, **param2):
es un método que puede aceptar un número arbitrario de valores con claves para*param2
param1
Es un parámetro simple.Por ejemplo, la sintaxis para implementar varargs en Java de la siguiente manera:
fuente