En este post explicaré para qué sirven y cómo se usan los *args y **kwargs en las llamadas a las funciones de Python 3.

Explicación de args y kwargs en Python. Función promedio

Explicación de args y kwargs en Python. Función promedio

Esto permite llamar a funciones que reciben un número indefinido de argumentos; y también cuando necesitamos múltiples argumentos opcionales. Vamos a ver algunos ejemplos.

Las funciones y los argumentos

Recordemos que las funciones son algo así:

def funcion(un_argumento)

Y que pueden tener más de un argumento:

def sumar(numero1, numero2)

O no tener ninguno:

def funcion()

Dentro de las funciones, se pueden usar a los argumentos para lo que sea necesario.

Explicando *args en Python

Este nombre no es obligatorio (la sintaxis sí), podría ser, por ejemplo, *argumentos o cualquier otra cosa siempre y cuando se ponga el asterisco antes del nombre.

Para ejemplificar esto, pongamos el ejemplo de una función que calcule el promedio de algunos valores. ¿Cuántos valores? no sabemos, por eso es que recibimos infinitos argumentos gracias a *args.

Dejaré que el código hable por mí:

La función es definida, pero con un argumento un poco especial: *numeros. Eso le indica a Python que sea una función que puede recibir desde 0 hasta infinitos argumentos. Así, se puede invocar a la misma con cualquier número de argumentos.

En este caso fue con argumentos enteros, pero podrían ser cadenas, URL’s de imágenes para descargar, etcétera. Lo importante o interesante es que podemos recorrer los argumentos

No es que esto sea algo nuevo, las funciones con un número indefinido

Más sobre *args en Python

Sólo para mencionar que podemos tener una función que reciba tanto un argumento posicional y los demás infinitos.

Por ejemplo, una que calcule promedios y reciba el nombre de una persona (sólo para ejemplificar) quedaría así:

def promedio(nombre, *argumentos)

Por cierto, no se puede tener dos veces a *args. Lo siguiente es erróneo:

def funcion(*argumentos, *otros_argumentos)

Y no se pueden tener a argumentos posicionales después de los argumentos infinitos. Lo siguiente no es correcto:

def function(*argumentos, un_argumento)

Uso de **kwargs en Python

Igualmente no es necesario poner kwargs, sino los dos asteriscos.

Por ejemplo, podría usarse el nombre de **argumentos_con_nombre ya que más o menos eso quieren decir (no literalmente, porque en inglés significa keyword arguments)

Estos kwargs en Python son usados para dos cosas que veremos a continuación.

Cuando una función recibe muchos argumentos

Por ejemplo, una función que conecte a MongoDB desde Python. Supongamos que queda así:

def conectar(host, puerto, usuario, palabra_secreta, nombre_base_de_datos)

Sé que no es tan larga, pero imaginemos que más adelante le agregamos más parámetros. Quedaría muy larga, mucho más. Así que mejor la definimos así:

def conectar(**opciones)

Veamos el código:

En él indicamos que vamos a recibir una lista de argumentos con nombre con los dos asteriscos **, y en la función accedemos a ellos como cuando accedemos a un diccionario.

Ahora vemos la llamada, la cual puede ser primero definiendo un diccionario y pasándolo con **:

El código de arriba confunde un poco, porque tenemos que usar ** al llamar a la función, aparte de cuando la definimos. La otra opción que es más expresiva y legible es la siguiente:

A mi parecer es más legible, y no hay necesidad de definir un diccionario. Además, el comportamiento dentro de la función es el mismo, al final es un diccionario que tiene claves y valores.

En caso de tener múltiples argumentos, pero que algunos sean opcionales

Ahora veamos otro uso clave de kwargs en Python. Esto va combinado con lo que vimos acerca de switch en Pyhton.

¿Qué pasa si algunos argumentos tienen valores por defecto o son opcionales? muy fácil, usamos al método get  de los diccionarios y proveemos un valor por defecto, algo así:

De esta manera, aunque no se proporcionen todos los datos (por ejemplo, pasar únicamente el usuario y la contraseña), no habrá errores:

conectar(usuario="parzibyte", palabra_secreta="hunter2")

En ese caso se tomarán los demás valores por defecto. Cabe mencionar que no tenemos que pasar a los argumentos en orden, lo de arriba igualmente podría ser así:

conectar(palabra_secreta="hunter2", usuario="parzibyte")

Esa es una de las ventajas de **kwargs en Python.

Diferencia entre **kwargs y *args en Python

Los **kwargs tienen nombre, aunque estén desordenados, pero tienen un nombre. En cambio, *args es una lista plana, no se sabe qué valor se encuentra en determinada posición.

Infiero que los keyword arguments son usados para definir valores por defecto en funciones que toman muchos de los mismos.

Usar argumentos, **kwargs y *args en Python en la misma función

Justo ahora no se me ocurre un uso, pero claro que se pueden usar en conjunto. Sólo recuerda estas reglas:

  1. Primero van los argumentos posicionales
  2. Luego, opcionalmente, va *args
  3. Finalmente, va **kwargs

Veamos este ejemplo:

En ese caso el argumento posicional es nombre, pero podría haber más. Después definimos los argumentos indefinidos, y finalmente pasamos los **kwargs. Recuerda que en lugar de estos últimos, podríamos definir un diccionario y pasarlo con **diccionario.

¿Quieres probar el código? puedes descargarlo y ejecutarlo, pero primero instala el intérprete de Python. O puedes ejecutarlo aquí, sin salir del post:

Espero que haya quedado claro. Si tienes dudas, ahí están los comentarios.

Estoy interesado en trabajar contigo de manera remota para llevar tu idea a la realidad, formar parte de tu equipo de desarrolladores, ayudarte con tu tarea, dar asesorías y todo lo relacionado con tecnología y programación. Contáctame para más información
No te vayas sin seguirme en Twitter, Facebook y GitHub
Si tienes dudas déjalas en un comentario, pero asegúrate de seguirme antes como agradecimiento (no te cuesta nada y me ayudas mucho)


parzibyte

He trabajado por más de 4 años en el desarrollo de software con experiencia en Java, PHP, JavaScript, HTML, Node.JS, Python, Android y Go. También he trabajado con bases de datos SQL como MySQL y SQLite, así como con bases de datos NoSQL usando MongoDB. Soy bueno utilizando algunos frameworks y herramientas como Firebase, jQuery, AngularJS, VueJS, CodeIgniter, Laravel, BulmaCSS, Bootstrap y Electron. Otros términos que conozco son: Arduino, GraphQL, API's, REST, AJAX, PouchDB, CouchDB, Experiencia de usuario, buenas prácticas de programación, Webpack, NPM, Administración de servidores y programación de scripts La plataforma en la que tengo más experiencia es la web, pero en mis ratos libres realizo unos pequeños ejercicios en C# y C. Estoy aquí para ayudarte a resolver tus problemas de programación y depuración :-)

1 Comment

Comprobar si diccionario tiene determinada clave en Python - Parzibyte's blog · enero 19, 2019 a las 1:01 am

[…] diccionarios en Python son útiles en muchas circunstancias. Por ejemplo, para eso de los args y kwargs, así como para usarlos como estructura de datos en donde se accede en un tiempo óptimo gracias a […]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

A %d blogueros les gusta esto: