Imagina que estás escribiendo un script y necesitas calcular el precio con IVA de varios productos en diferentes partes de tu código. Si copias y pegas la misma fórmula matemática una y otra vez, tu programa se volverá largo, difícil de leer y, lo peor de todo, una pesadilla de mantener. Si el IVA cambia del 21% al 10%, tendrás que buscar y modificar cada línea a mano.
En el desarrollo de software existe un principio sagrado llamado DRY (Don’t Repeat Yourself o «No te repitas»). Para cumplirlo, disponemos de una herramienta extremadamente potente: las funciones.
En este tutorial vas a aprender a definir y usar funciones en Python paso a paso. Descubriremos la diferencia real entre print() y return, y aprenderemos a crear código limpio, modular y reutilizable.
Aquí tienes un ejemplo rápido de cómo una función puede simplificar tu vida como programador:
# Definir la función una sola vez
def calcular_precio_final(precio_base):
iva = 1.21
return precio_base * iva
# Usarla tantas veces como quieras en una sola línea
producto_a = calcular_precio_final(100)
producto_b = calcular_precio_final(45)
print(f"Precios finales: {producto_a}€ y {producto_b}€")
1. ¿Qué es una Función? La Analogía de la Batidora
Una función es un bloque de código organizado y reutilizable que se diseña para realizar una única tarea específica. Piensa en ella como una **batidora de cocina**:
- Entrada (Ingredientes): Le introduces frutas, leche o azúcar (estos son los parámetros).
- Procesamiento (Cuchillas): La batidora tritura y mezcla todo de forma interna según un programa predefinido (este es el cuerpo de la función).
- Salida (Batido): Te devuelve un delicioso zumo listo para servir (este es el valor de retorno o
return).
Lo fantástico de la batidora es que no necesitas saber cómo giran los engranajes del motor cada vez que quieres un batido; solo necesitas saber qué ingredientes meter y qué producto vas a obtener.
2. Cómo Definir y Llamar a una Función en Python
Para crear una función propia en Python, utilizamos la palabra reservada def (abreviatura de *define*). La sintaxis es muy sencilla y estructurada:
def nombre_de_la_funcion(parametro1, parametro2):
# Cuerpo de la función (código indentado)
resultado = parametro1 + parametro2
return resultado
Escribamos una función real que reciba un nombre y devuelva un saludo personalizado:
# 1. Definición de la función
def saludar(nombre):
mensaje = f"¡Hola, {nombre}! Bienvenido a Todo Python."
return mensaje
# 2. Llamada o ejecución de la función
saludo_final = saludar("Alba")
print(saludo_final) # Salida: ¡Hola, Alba! Bienvenido a Todo Python.
Diferencia Clave: Parámetros vs Argumentos
Es muy común escuchar ambos términos como sinónimos, pero técnicamente hay una diferencia fundamental:
- Los parámetros son los nombres de las variables temporales que escribes al definir la función. Son como «huecos vacíos» esperando ser llenados. En el ejemplo anterior,
nombrees el parámetro. - Los argumentos son los valores reales que le pasas a la función al llamarla. En el ejemplo, la cadena de texto
"Alba"es el argumento.
3. La Diferencia de Oro: print() vs return
Este es el tropiezo más común de cualquier principiante en la programación. Muchos se preguntan: «Si puedo usar print() dentro de mi función para mostrar el resultado, ¿para qué necesito return?».
Volvamos a nuestra analogía de la batidora:
- Usar
print()es como si la batidora hiciera el zumo y lo pusiera en una vitrina cerrada. Puedes verlo (se muestra en la pantalla de la consola), pero no puedes beberlo, ni guardarlo en la nevera, ni usarlo para otra receta. El código de fuera de la función no puede acceder a ese dato. - Usar
returnes como si la batidora te entregara el vaso de zumo en la mano. Ahora puedes guardarlo en una variable, realizar operaciones matemáticas con él, o pasárselo a otra parte de tu programa.
Veamos la diferencia en código real:
# Función que solo imprime (NO devuelve nada)
def sumar_con_print(a, b):
print(a + b)
# Función que devuelve el resultado
def sumar_con_return(a, b):
return a + b
# Intentemos usar los resultados
resultado_print = sumar_con_print(5, 5) # Muestra 10 en pantalla
print(resultado_print) # Salida: None (¡El dato se ha perdido para siempre!)
resultado_return = sumar_con_return(5, 5) # Guarda el 10 en la variable
precio_con_descuento = resultado_return - 2 # ¡Podemos operar con él!
print(precio_con_descuento) # Salida: 8
Como regla general: **usa siempre return** a menos que tu función tenga la misión explícita de pintar algo en pantalla o guardar un archivo.
4. Flexibilidad: Argumentos por Defecto y Nombrados
Python nos ofrece formas fantásticas de hacer que nuestras funciones sean dinámicas y fáciles de usar.
Argumentos Opcionales (Valores por Defecto)
Puedes asignar un valor por defecto a los parámetros en la cabecera de la función. Si la persona que llama a la función no proporciona ese argumento, Python utilizará el valor predeterminado:
def saludar_usuario(nombre, saludo="Hola"):
return f"{saludo}, {nombre}!"
# Usando el valor por defecto
print(saludar_usuario("Carlos")) # Salida: Hola, Carlos!
# Sobrescribiendo el valor por defecto
print(saludar_usuario("Carlos", "Buenos días")) # Salida: Buenos días, Carlos!
Argumentos Nombrados (Keyword Arguments)
Por defecto, Python asocia los argumentos a los parámetros por su posición. Sin embargo, puedes especificar el nombre del parámetro de forma explícita al llamar a la función, lo que te permite alterar el orden o hacer tu código mucho más legible:
def crear_perfil(nombre, edad, pais):
return f"{nombre} tiene {edad} años y vive en {pais}."
# Llamada por posición (orden estricto)
print(crear_perfil("Lucía", 28, "España"))
# Llamada por nombre (el orden ya no importa)
print(crear_perfil(pais="España", nombre="Lucía", edad=28))
5. Errores Comunes con Funciones y Cómo Solucionarlos
Incluso los desarrolladores experimentados cometen pequeños descuidos con las funciones. Conocer estos dos errores típicos te ahorrará horas de depuración:
❌ Error de Ámbito (Scope)
Las variables que creas dentro de una función son locales. Esto significa que solo existen dentro de esa función. En cuanto el código de la función termina de ejecutarse con el return, esas variables desaparecen.
# CÓDIGO CON ERROR
def calcular():
resultado_interno = 42
return resultado_interno
calcular()
print(resultado_interno) # NameError: name 'resultado_interno' is not defined
- Solución: Si necesitas el valor de
resultado_internofuera de la función, devuélvelo mediantereturny guárdalo en una variable global en el flujo de tu programa:
# CÓDIGO CORRECTO
resultado_externo = calcular()
print(resultado_externo) # Salida: 42
❌ TypeError por Argumentos Faltantes
Si defines una función con ciertos parámetros obligatorios (los que no tienen valor por defecto) y te olvidas de pasárselos al llamarla, Python lanzará un error.
# ERROR: TypeError: sumar() missing 1 required positional argument: 'b'
def sumar(a, b):
return a + b
sumar(10) # Solo le pasamos un argumento
- Solución: Pasa siempre el número de argumentos que coincida con los parámetros obligatorios de la definición, o añade valores por defecto para hacerlos opcionales.
Conclusión y Siguiente Paso
Las **funciones en Python** son bloques clave que transforman tu forma de escribir código. Gracias a ellas, evitas repetir líneas innecesariamente, facilitas la depuración de errores y logras que tu software sea verdaderamente profesional y modular.
Para seguir construyendo sobre este conocimiento, te recomendamos repasar cómo interactúan las funciones con los bucles en Python para procesar listas complejas de datos.
El siguiente paso natural en nuestro roadmap es aprender a gestionar conjuntos estructurados de información utilizando las colecciones clave del lenguaje: las **Listas y Sets en Python**. ¡Te esperamos en la siguiente entrega!

