A veces queremos crear funciones que reciban un número variable de argumentos.
Por ejemplo, supón esta función sencilla 👇
Si intentamos pasar más de dos argumentos:
⛔ Python nos dirá:
TypeError: multiplicacion() takes 2 positional arguments but 3 were given
**Podemos reemplazar los parámetros fijos (x, y) por uno solo, precedido de un asterisco ⭐
Cuando usamos el asterisco, todos los argumentos que se pasen se agrupan dentro de una tupla.
⬇️ Salida esperada:
(2, 3, 4, 5)
🧠 Lo que obtenemos es una tupla, similar a una lista,
pero inmutable (no se puede modificar).
Por eso se escribe entre paréntesis
()en lugar de corchetes[].
Como numeros es una tupla iterable, podemos recorrerla con un bucle for 👇
⬇️ Salida:
Número: 2
Número: 3
Número: 4
Número: 5
Vamos a usar una variable acumuladora llamada total, que comienza en 1 y se multiplica por cada número.
⬇️ Ejemplo de uso:
Un error común es poner return dentro del for, así 👇
🧩 Debe ir fuera del bucle, al mismo nivel de indentación:
Un error común es poner return dentro del for, así 👇
¿Qué pasa si nadie pasa números?
Podemos decidir entre dos comportamientos:
✅ Matemático: retornar 1 ❌ Defensivo: lanzar un error
La librería estándar incluye math.prod() para calcular el producto de un iterable directamente.
🧠 Es más corto, más rápido y hace exactamente lo mismo.
Si ya tienes tus números en una lista o tupla, puedes desempaquetarlos con * al llamar la función 👇
💬 El mismo símbolo
*empaqueta al definir y desempaqueta al llamar.
**kwargs (nombre + valor)De forma similar, **kwargs permite recibir argumentos con nombre, que se guardan en un diccionario 🗂️
⬇️ Salida:
args: (1, 2, 3)
kwargs: {'base': 10, 'sep': '-'}
**kwargs?El parámetro **kwargs te permite crear funciones flexibles,
que aceptan parámetros opcionales con nombre 🧠
Esto es muy útil cuando no sabes exactamente qué opciones
puede necesitar el usuario o cuando quieres dar valores personalizados.
Queremos una función que salude, pero que también permita personalizar el saludo.
⬇️ Salida esperada:
Hola, Danna
Hola, Danna 🐍
HOLA, DANNA 💫
💡 Cada parámetro con nombre (
emoji,mayusculas) se almacena dentro del diccionariokwargs.
Agreguemos un print para ver qué llega a la función:
⬇️ Salida:
{'emoji': '🌟', 'mayusculas': True}
HOLA, DANNA 🌟
| Tipo | Símbolo | Qué guarda | Ejemplo recibido |
|---|---|---|---|
*args |
* |
Tupla con valores sin nombre | (1, 2, 3) |
**kwargs |
** |
Diccionario con nombre y valor | {'emoji': '🌟'} |
🔸 Usa
*argscuando los valores no tienen nombre 🔸 Usa**kwargscuando los valores tienen nombre
Podemos usar *args y **kwargs juntos. Por ejemplo, una función que recibe datos sueltos y opciones nombradas:
⬇️ Salida:
args: (1, 2, 3)
kwargs: {'nombre': 'Danna', 'curso': 'Python'}
**?El doble asterisco (**) se usa cuando queremos desempaquetar un diccionario y pasarlo como argumentos con nombre a una función 🗝️
Esto ocurre cuando ya tenemos los valores guardados
en un diccionario y queremos usarlos sin escribir cada uno manualmente.
Supón esta función:
Y tenemos un diccionario con la información 👇
⬇️ Salida:
Me llamo Danna y tengo 28 años.
🧠 Python toma las claves del diccionario como nombres de parámetros, y los valores como los datos que se pasan a la función.
| Forma | Qué hace | Ejemplo |
|---|---|---|
*lista |
Desempaqueta valores sin nombre | f(*[1, 2]) |
**diccionario |
Desempaqueta pares nombre=valor | f(**{"x":1, "y":2}) |
🔹 Usa
*cuando tengas una secuencia (lista, tupla) 🔹 Usa**cuando tengas un diccionario con nombres de variables
✅ *args → empaqueta/desempaqueta valores sueltos ✅ **kwargs → empaqueta/desempaqueta valores con nombre ✅ ** al llamar → toma claves y valores de un diccionario
Con esto ya dominas todas las formas en que Python puede recibir y expandir argumentos 🐍💫