Hay un momento en el aprendizaje de Python en el que todo cambia. Un momento en el que dejas de escribir código como una lista interminable de instrucciones y empiezas a estructurarlo de forma limpia, reutilizable y profesional.
Ese momento ocurre cuando aprendes a usar funciones.
Las funciones son uno de los conceptos más importantes de cualquier lenguaje de programación. Son la base de todo código bien escrito. Y en Python, crearlas es tan sencillo que en los próximos minutos ya estarás escribiendo las tuyas propias.
Vamos paso a paso.
¿Qué es una función en Python?
Una función es un bloque de código con nombre que realiza una tarea específica y puede ejecutarse (llamarse) desde cualquier parte de tu programa, las veces que necesites.
La analogía perfecta: imagina que eres el chef de un restaurante y tienes que preparar pasta todos los días. Podrías escribir los pasos cada vez que la preparas, o podrías crear una receta con un nombre ("preparar_pasta") y simplemente ejecutarla cuando la necesites.
Eso es exactamente una función: una receta reutilizable para una tarea específica.
Python ya incluye muchas funciones listas para usar. Las has estado usando desde el primer día:
print("Hola, mundo") # función print()
len("Python") # función len()
int("25") # función int()
type(42) # función type()Todas esas son funciones integradas de Python. Pero lo mejor es que puedes crear las tuyas propias para resolver exactamente los problemas que necesitas resolver.
¿Por qué usar funciones?
Antes de ver cómo crearlas, entendamos por qué importan tanto. Hay tres razones principales:
1. 🔁 Reutilización — escribe una vez, usa muchas veces
# ❌ Sin funciones: repetir el mismo código 3 veces
print("Bienvenido, Ana. Tienes 3 mensajes nuevos.")
print("Bienvenido, Luis. Tienes 1 mensaje nuevo.")
print("Bienvenido, María. Tienes 7 mensajes nuevos.")
# ✅ Con funciones: definir una vez, llamar las veces que quieras
def bienvenida(nombre, mensajes):
print(f"Bienvenido, {nombre}. Tienes {mensajes} mensaje(s) nuevo(s).")
bienvenida("Ana", 3)
bienvenida("Luis", 1)
bienvenida("María", 7)2. 📦 Organización — código más limpio y legible
Un programa bien estructurado con funciones se lee casi como un libro. Cada función tiene un nombre descriptivo que dice exactamente qué hace. No tienes que leer 50 líneas de código para entender qué está pasando: lees los nombres de las funciones.
3. 🐛 Mantenimiento — un cambio en un solo lugar
Si necesitas modificar cómo funciona algo, solo cambias la función. Sin funciones, tendrías que buscar y cambiar ese código en cada lugar donde lo repetiste. Con funciones, lo cambias una vez y el cambio se aplica en todas partes.
Paso 1: Tu primera función — la sintaxis básica
Crear una función en Python es muy sencillo. Usa la palabra clave def, seguida del nombre de la función, paréntesis y dos puntos. El código de la función va indentado:
def saludar():
print("¡Hola! Bienvenido a Python.")
print("Las funciones son geniales.")Eso define la función. Pero definirla no la ejecuta. Para ejecutarla, la llamas por su nombre seguido de paréntesis:
saludar() # llamada a la función¡Hola! Bienvenido a Python.
Las funciones son geniales.Puedes llamarla tantas veces como quieras:
saludar()
saludar()
saludar()
# Imprime el mensaje 3 veces con una sola línea cada vez💡 Regla importante: Siempre define la función antes de llamarla. Python lee el código de arriba hacia abajo, así que si llamas a una función antes de definirla, obtendrás un error.
Paso 2: Parámetros — dale información a tu función
Las funciones sin parámetros siempre hacen exactamente lo mismo. Eso está bien para algunas tareas, pero la mayoría de las veces querrás que la función trabaje con datos diferentes cada vez que la llamas.
Para eso existen los parámetros: variables que defines en la función y que reciben valores cuando la llamas.
# Función con un parámetro
def saludar(nombre):
print(f"¡Hola, {nombre}! Bienvenido a Python.")
saludar("Ana") # Hola, Ana! Bienvenido a Python.
saludar("Luis") # Hola, Luis! Bienvenido a Python.
saludar("María") # Hola, María! Bienvenido a Python.Con múltiples parámetros:
# Función con varios parámetros
def presentar(nombre, edad, ciudad):
print(f"Me llamo {nombre}, tengo {edad} años y soy de {ciudad}.")
presentar("Ana", 25, "Ciudad de México")
presentar("Luis", 30, "Bogotá")Me llamo Ana, tengo 25 años y soy de Ciudad de México.
Me llamo Luis, tengo 30 años y soy de Bogotá.Parámetros vs Argumentos: la diferencia
Son términos que se confunden mucho. La diferencia es simple:
- Parámetro — la variable en la definición de la función (
nombre,edad) - Argumento — el valor que pasas al llamarla (
"Ana",25)
def saludar(nombre): # 'nombre' es el PARÁMETRO
print(f"Hola, {nombre}")
saludar("Ana") # "Ana" es el ARGUMENTOPaso 3: return — devolver resultados
Hasta ahora nuestras funciones solo imprimen cosas. Pero muchas veces necesitas que la función calcule algo y te devuelva el resultado para seguir usándolo en tu programa.
Para eso existe return:
# Sin return — solo imprime, no devuelve nada útil
def sumar_sin_return(a, b):
print(a + b)
resultado = sumar_sin_return(5, 3)
print(resultado) # None ← no puedes usar este valor# Con return — devuelve el valor para usarlo después
def sumar(a, b):
return a + b
resultado = sumar(5, 3)
print(resultado) # 8
print(sumar(10, 20) * 2) # 60 ← puedes operar con el resultado
print(f"La suma es: {sumar(7, 9)}") # La suma es: 16La diferencia es crucial: print() muestra algo en pantalla pero no devuelve nada usable. return devuelve un valor que puedes guardar en una variable, pasar a otra función o usar en cualquier expresión.
Retornar múltiples valores
Python te permite retornar varios valores a la vez, algo que muchos otros lenguajes no permiten tan fácilmente:
def calcular_estadisticas(numeros):
minimo = min(numeros)
maximo = max(numeros)
promedio = sum(numeros) / len(numeros)
return minimo, maximo, promedio # devuelve 3 valores
datos = [4, 8, 15, 16, 23, 42]
min_val, max_val, prom = calcular_estadisticas(datos)
print(f"Mínimo: {min_val}") # 4
print(f"Máximo: {max_val}") # 42
print(f"Promedio: {prom:.1f}") # 18.0Paso 4: Parámetros con valores por defecto
A veces quieres que un parámetro sea opcional: si el usuario no lo especifica, usa un valor predeterminado. Para eso se usan los valores por defecto:
def saludar(nombre, saludo="Hola"):
print(f"{saludo}, {nombre}!")
saludar("Ana") # Hola, Ana! ← usa el valor por defecto
saludar("Luis", "Buenos días") # Buenos días, Luis! ← usa el valor pasado
saludar("María", saludo="Qué tal") # Qué tal, María!Un ejemplo más práctico:
def calcular_precio(precio_base, descuento=0, impuesto=0.19):
precio_con_descuento = precio_base * (1 - descuento)
precio_final = precio_con_descuento * (1 + impuesto)
return round(precio_final, 2)
print(calcular_precio(100)) # 119.0 (sin descuento, con IVA normal)
print(calcular_precio(100, descuento=0.10)) # 107.1 (10% descuento)
print(calcular_precio(100, 0.20, 0.16)) # 92.8 (20% descuento, 16% impuesto)⚠️ Regla importante: Los parámetros con valores por defecto siempre van después de los parámetros obligatorios. Si los pones antes, Python te dará un error de sintaxis.
# ❌ Error: parámetro con default antes de obligatorio
def saludar(saludo="Hola", nombre):
...
# ✅ Correcto: obligatorios primero, con default después
def saludar(nombre, saludo="Hola"):
...Paso 5: *args y **kwargs — parámetros flexibles
¿Qué pasa cuando no sabes de antemano cuántos argumentos va a recibir tu función? Python tiene dos herramientas para eso.
*args — cantidad variable de argumentos posicionales
def sumar_todo(*numeros):
total = 0
for n in numeros:
total += n
return total
print(sumar_todo(1, 2, 3)) # 6
print(sumar_todo(10, 20, 30, 40)) # 100
print(sumar_todo(5)) # 5
print(sumar_todo()) # 0El * antes del nombre indica que Python empaquetará todos los argumentos en una tupla. Puedes nombrarla como quieras, pero la convención es args.
**kwargs — cantidad variable de argumentos con nombre
def crear_perfil(**datos):
print("Perfil de usuario:")
for clave, valor in datos.items():
print(f" {clave}: {valor}")
crear_perfil(nombre="Ana", edad=25, ciudad="Lima", lenguaje="Python")
# Perfil de usuario:
# nombre: Ana
# edad: 25
# ciudad: Lima
# lenguaje: PythonEl ** empaqueta los argumentos con nombre en un diccionario. La convención es kwargs (keyword arguments).
Combinándolos todos
def funcion_completa(obligatorio, por_defecto="default", *args, **kwargs):
print(f"Obligatorio: {obligatorio}")
print(f"Por defecto: {por_defecto}")
print(f"Args extra: {args}")
print(f"Kwargs: {kwargs}")
funcion_completa("requerido", "personalizado", 1, 2, 3, a=10, b=20)
# Obligatorio: requerido
# Por defecto: personalizado
# Args extra: (1, 2, 3)
# Kwargs: {'a': 10, 'b': 20}Paso 6: Scope — dónde viven las variables
El scope (ámbito) define en qué partes del código es accesible una variable. En Python, las variables creadas dentro de una función son locales: solo existen dentro de esa función.
def mi_funcion():
variable_local = "Solo existo dentro de la función"
print(variable_local) # ✅ Funciona
mi_funcion()
print(variable_local) # ❌ NameError: no existe fuera de la funciónvariable_global = "Existo en todo el programa"
def mi_funcion():
print(variable_global) # ✅ Puede leer variables globales
mi_funcion()
print(variable_global) # ✅ También accesible aquí💡 Buena práctica: Evita modificar variables globales desde dentro de las funciones. Es mejor pasar los valores como parámetros y retornar los resultados. Tu código será más predecible y fácil de depurar.
Paso 7: Funciones Lambda — funciones en una línea
Las funciones lambda son funciones anónimas y compactas que se definen en una sola línea. Son perfectas para operaciones simples que no necesitan un nombre permanente.
# Función normal
def cuadrado(x):
return x ** 2
# Equivalente con lambda
cuadrado_lambda = lambda x: x ** 2
print(cuadrado(5)) # 25
print(cuadrado_lambda(5)) # 25Las lambdas brillan cuando las usas junto con funciones como map(), filter() y sorted():
numeros = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
# Ordenar de mayor a menor
ordenados = sorted(numeros, key=lambda x: -x)
print(ordenados) # [9, 6, 5, 5, 4, 3, 3, 2, 1, 1]
# Solo los números pares
pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares) # [4, 2, 6]
# Multiplicar cada número por 10
multiplicados = list(map(lambda x: x * 10, numeros))
print(multiplicados) # [30, 10, 40, 10, 50, 90, 20, 60, 50, 30]Paso 8: Docstrings — documenta tus funciones
Un código profesional siempre documenta sus funciones. En Python, esto se hace con los docstrings: cadenas de texto que van justo después de la definición de la función y explican qué hace, qué recibe y qué devuelve.
def calcular_imc(peso, altura):
"""
Calcula el Índice de Masa Corporal (IMC).
Args:
peso (float): Peso en kilogramos.
altura (float): Altura en metros.
Returns:
float: El IMC calculado, redondeado a 2 decimales.
Examples:
>>> calcular_imc(70, 1.75)
22.86
"""
imc = peso / (altura ** 2)
return round(imc, 2)
# Puedes ver el docstring así:
help(calcular_imc)
print(calcular_imc.__doc__)
# Uso:
print(calcular_imc(70, 1.75)) # 22.86
print(calcular_imc(90, 1.80)) # 27.78Puede parecer un detalle menor cuando estás empezando, pero cuando revises código que escribiste hace 6 meses (o cuando otro desarrollador revise el tuyo), los docstrings valen su peso en oro.
Ejemplo final: juntando todo en un proyecto real
Vamos a construir una pequeña calculadora de notas escolares que usa todo lo que aprendiste en este artículo:
# ============================================
# CALCULADORA DE NOTAS ESCOLARES
# ============================================
def calcular_promedio(*notas):
"""Calcula el promedio de una lista de notas."""
if not notas:
return 0
return round(sum(notas) / len(notas), 2)
def clasificar_nota(promedio, aprobacion=6.0):
"""
Clasifica el rendimiento según el promedio.
Args:
promedio (float): Promedio del estudiante.
aprobacion (float): Nota mínima para aprobar (default: 6.0).
Returns:
str: Clasificación del rendimiento.
"""
if promedio >= 9.0:
return "Excelente ⭐"
elif promedio >= 7.5:
return "Muy bien 👍"
elif promedio >= aprobacion:
return "Aprobado ✅"
else:
return "Reprobado ❌"
def reporte_estudiante(nombre, *notas, aprobacion=6.0):
"""Genera un reporte completo de un estudiante."""
promedio = calcular_promedio(*notas)
clasificacion = clasificar_nota(promedio, aprobacion)
print(f"\n{'='*40}")
print(f" Reporte de: {nombre}")
print(f"{'='*40}")
print(f" Notas: {list(notas)}")
print(f" Promedio: {promedio}")
print(f" Resultado: {clasificacion}")
print(f"{'='*40}")
return promedio
# Generar reportes
reporte_estudiante("Ana García", 8.5, 9.0, 7.5, 9.5, 8.0)
reporte_estudiante("Luis Pérez", 5.0, 6.5, 4.5, 7.0, 5.5)
reporte_estudiante("María López", 10, 9.5, 10, 9.0, 9.8)========================================
Reporte de: Ana García
========================================
Notas: [8.5, 9.0, 7.5, 9.5, 8.0]
Promedio: 8.5
Resultado: Muy bien 👍
========================================
========================================
Reporte de: Luis Pérez
========================================
Notas: [5.0, 6.5, 4.5, 7.0, 5.5]
Promedio: 5.7
Resultado: Reprobado ❌
========================================
========================================
Reporte de: María López
========================================
Notas: [10, 9.5, 10, 9.0, 9.8]
Promedio: 9.66
Resultado: Excelente ⭐
========================================Errores comunes al usar funciones en Python
Llamar la función sin paréntesis
def saludar():
print("Hola")
saludar # ❌ No hace nada, solo referencia la función
saludar() # ✅ Ejecuta la funciónConfundir print() con return
def sumar(a, b):
print(a + b) # ❌ Muestra el resultado pero no lo devuelve
resultado = sumar(5, 3) # resultado = None (no el número 8)
print(resultado * 2) # Error: no puedes multiplicar NonePoner parámetros con default antes de los obligatorios
def saludar(saludo="Hola", nombre): # ❌ SyntaxError
...
def saludar(nombre, saludo="Hola"): # ✅ Correcto
...Intentar acceder a variables locales desde fuera
def mi_funcion():
resultado = 42
mi_funcion()
print(resultado) # ❌ NameError: resultado no existe fueraBuenas prácticas para escribir funciones en Python
- ✅ Una función, una responsabilidad — cada función debe hacer una sola cosa y hacerla bien
- ✅ Nombres descriptivos —
calcular_promedio()es mejor quecalc()of() - ✅ Funciones cortas — si tu función tiene más de 20-30 líneas, probablemente debería dividirse
- ✅ Usa return en lugar de print() cuando quieras usar el resultado
- ✅ Documenta con docstrings — especialmente si otros van a usar tu código
- ✅ Evita variables globales — pasa los valores como parámetros
- ✅ Los parámetros con default al final — obligatorios primero
Resumen: lo que aprendiste hoy
- ✅ Una función es un bloque de código reutilizable definido con
def - ✅ Los parámetros reciben datos; los argumentos son los valores que pasas
- ✅
returndevuelve un valor usable;print()solo lo muestra - ✅ Los valores por defecto hacen que un parámetro sea opcional
- ✅
*argsacepta número variable de argumentos posicionales - ✅
**kwargsacepta número variable de argumentos con nombre - ✅ Las variables locales solo existen dentro de su función
- ✅ Las funciones lambda son funciones anónimas de una sola línea
- ✅ Los docstrings documentan qué hace la función, qué recibe y qué devuelve
🧪 ¿Tienes los fundamentos de Python bien sólidos?
Las funciones son uno de los temas que más aparece en cualquier evaluación de Python. Si quieres saber qué tan sólidos están tus fundamentos — variables, tipos de datos, bucles y ahora funciones — este es el momento perfecto para comprobarlo.
👉 Test: Python Básico 👉 Test: Python Intermedio
¿Ya usabas funciones o era la primera vez que las veías? ¿Cuál fue el concepto que más te costó entender: el return, el scope o los *args? Cuéntanos en los comentarios 👇 — respondemos todos. 🐍
No hay comentarios todavía. Sé el primero en compartir tu opinión.