Python
Tutorial Python: Funciones
Aprende las funciones en Python: definición, parámetros, return y docstrings para escribir código organizado y reutilizable.
Aprende Python y certifícateDefinición básica superficial
Las funciones en Python son bloques de código reutilizables que realizan una tarea específica. Puedes imaginarlas como pequeñas "recetas" que puedes llamar cuando necesites ejecutar esa tarea en particular, sin tener que escribir el mismo código una y otra vez.
Una función en Python se define utilizando la palabra clave def
, seguida del nombre de la función y paréntesis. El código que forma parte de la función debe estar indentado (con 4 espacios, según la convención de Python).
def saludar():
print("¡Hola, mundo!")
Para ejecutar o "llamar" a una función, simplemente escribes su nombre seguido de paréntesis:
saludar() # Imprime: ¡Hola, mundo!
Las funciones son fundamentales en la programación porque nos permiten:
- Organizar el código en bloques lógicos y manejables
- Reutilizar código en diferentes partes de nuestro programa
- Simplificar la lectura y mantenimiento del código
Veamos un ejemplo práctico de una función que calcula el área de un rectángulo:
def calcular_area_rectangulo(base, altura):
area = base * altura
return area
# Uso de la función
resultado = calcular_area_rectangulo(5, 3)
print(f"El área del rectángulo es: {resultado}") # Imprime: El área del rectángulo es: 15
En este ejemplo, calcular_area_rectangulo
es una función que:
- Recibe dos valores (base y altura)
- Realiza un cálculo con ellos
- Devuelve el resultado
Las funciones pueden ser tan simples o complejas como necesites, pero una buena práctica es que cada función realice una única tarea específica. Esto hace que tu código sea más fácil de entender, probar y mantener.
# Función que verifica si un número es par
def es_par(numero):
return numero % 2 == 0
# Función que convierte temperatura de Celsius a Fahrenheit
def celsius_a_fahrenheit(celsius):
return (celsius * 9/5) + 32
En Python, las funciones son ciudadanos de primera clase, lo que significa que pueden ser:
- Asignadas a variables
- Pasadas como argumentos a otras funciones
- Devueltas como resultado de otras funciones
# Asignar una función a una variable
convertir = celsius_a_fahrenheit
temperatura_f = convertir(25) # Equivalente a celsius_a_fahrenheit(25)
print(f"25°C equivalen a {temperatura_f}°F") # Imprime: 25°C equivalen a 77.0°F
Las funciones en Python también pueden tener un ámbito (scope), lo que significa que las variables definidas dentro de una función solo existen dentro de esa función, a menos que se devuelvan explícitamente.
def calcular_descuento(precio, porcentaje=10):
# La variable 'descuento' solo existe dentro de esta función
descuento = precio * (porcentaje / 100)
precio_final = precio - descuento
return precio_final
precio_con_descuento = calcular_descuento(100)
print(f"Precio con descuento: {precio_con_descuento}") # Imprime: Precio con descuento: 90.0
# print(descuento) # Esto daría error porque 'descuento' no existe fuera de la función
En resumen, las funciones son herramientas esenciales que nos permiten escribir código más organizado, reutilizable y mantenible. Son como pequeñas máquinas especializadas que podemos invocar cuando necesitamos realizar una tarea específica en nuestro programa.
Parámetros y argumentos
Los parámetros y argumentos son elementos fundamentales que permiten que nuestras funciones sean verdaderamente útiles y flexibles. Estos conceptos están relacionados pero tienen diferencias importantes que debemos entender.
Un parámetro es una variable que se define en la declaración de una función. Actúa como un espacio reservado para los datos que la función necesita para realizar su tarea. Por otro lado, un argumento es el valor real que pasamos a la función cuando la llamamos.
def saludar_persona(nombre): # 'nombre' es un parámetro
print(f"Hola, {nombre}!")
saludar_persona("Ana") # "Ana" es un argumento
En este ejemplo, nombre
es el parámetro (la variable que espera recibir la función) y "Ana"
es el argumento (el valor concreto que le pasamos).
Tipos de parámetros
Python ofrece varios tipos de parámetros que nos dan flexibilidad al diseñar nuestras funciones:
Parámetros posicionales
Son los más básicos y se asignan según el orden en que se pasan los argumentos:
def calcular_precio_final(precio_base, impuesto):
return precio_base + (precio_base * impuesto)
total = calcular_precio_final(100, 0.21) # 100 va a precio_base, 0.21 va a impuesto
print(f"Precio final: {total}") # Imprime: Precio final: 121.0
Parámetros con valores predeterminados
Permiten especificar un valor por defecto que se usará si no se proporciona un argumento:
def saludar(nombre, mensaje="¡Bienvenido!"):
print(f"Hola {nombre}. {mensaje}")
saludar("Carlos") # Usa el mensaje predeterminado
# Imprime: Hola Carlos. ¡Bienvenido!
saludar("María", "¿Cómo estás hoy?") # Usa el mensaje personalizado
# Imprime: Hola María. ¿Cómo estás hoy?
Los parámetros con valores predeterminados deben aparecer después de los parámetros sin valores predeterminados:
# Correcto
def crear_perfil(nombre, edad, ciudad="Madrid"):
return f"Perfil: {nombre}, {edad} años, {ciudad}"
# Incorrecto - causaría un error de sintaxis
# def crear_perfil(nombre, ciudad="Madrid", edad):
# return f"Perfil: {nombre}, {edad} años, {ciudad}"
Parámetros por nombre
Podemos especificar explícitamente qué valor corresponde a cada parámetro, independientemente del orden:
def dividir(dividendo, divisor):
return dividendo / divisor
# Usando argumentos posicionales
resultado1 = dividir(10, 2) # resultado1 = 5.0
# Usando argumentos por nombre
resultado2 = dividir(divisor=2, dividendo=10) # resultado2 = 5.0
Los argumentos por nombre son especialmente útiles cuando una función tiene muchos parámetros o cuando queremos hacer que nuestro código sea más legible:
def crear_usuario(nombre, apellido, edad, email, activo=True):
return {
"nombre_completo": f"{nombre} {apellido}",
"edad": edad,
"email": email,
"activo": activo
}
# Más fácil de leer con argumentos por nombre
usuario = crear_usuario(
nombre="Juan",
apellido="Pérez",
edad=28,
email="juan@ejemplo.com",
activo=False
)
Combinando tipos de parámetros
Podemos combinar diferentes tipos de parámetros en una misma función:
def calcular_pago(horas, tarifa=15, moneda="EUR"):
total = horas * tarifa
return f"{total} {moneda}"
# Diferentes formas de llamar a la función
pago1 = calcular_pago(40) # 40 horas, tarifa predeterminada, moneda predeterminada
pago2 = calcular_pago(35, 20) # 35 horas, tarifa de 20, moneda predeterminada
pago3 = calcular_pago(30, moneda="USD") # 30 horas, tarifa predeterminada, moneda USD
pago4 = calcular_pago(horas=25, tarifa=18, moneda="GBP") # Todo especificado por nombre
print(pago1) # Imprime: 600 EUR
print(pago2) # Imprime: 700 EUR
print(pago3) # Imprime: 450 USD
print(pago4) # Imprime: 450 GBP
Validación de argumentos
Es una buena práctica validar los argumentos que recibe una función para asegurarnos de que son del tipo y valor esperados:
def calcular_descuento(precio, porcentaje):
# Validación de argumentos
if not isinstance(precio, (int, float)) or precio < 0:
raise ValueError("El precio debe ser un número positivo")
if not isinstance(porcentaje, (int, float)) or not (0 <= porcentaje <= 100):
raise ValueError("El porcentaje debe ser un número entre 0 y 100")
# Cálculo del descuento
descuento = precio * (porcentaje / 100)
return precio - descuento
try:
precio_final = calcular_descuento(100, 15)
print(f"Precio con descuento: {precio_final}") # Imprime: Precio con descuento: 85.0
# Esto lanzará un error
precio_erroneo = calcular_descuento(-50, 10)
except ValueError as e:
print(f"Error: {e}") # Imprime: Error: El precio debe ser un número positivo
Número variable de argumentos
En ocasiones, necesitamos funciones que puedan aceptar un número variable de argumentos. Python nos ofrece dos sintaxis especiales para esto:
Argumentos posicionales variables (*args)
Permite que una función acepte cualquier número de argumentos posicionales:
def sumar(*numeros):
total = 0
for numero in numeros:
total += numero
return total
# Podemos pasar cualquier cantidad de argumentos
print(sumar(1, 2)) # Imprime: 3
print(sumar(1, 2, 3, 4, 5)) # Imprime: 15
print(sumar()) # Imprime: 0
El parámetro *numeros
recibe todos los argumentos posicionales como una tupla.
Argumentos por nombre variables (**kwargs)
Permite que una función acepte cualquier número de argumentos por nombre:
def mostrar_informacion(**datos):
for clave, valor in datos.items():
print(f"{clave}: {valor}")
# Podemos pasar cualquier cantidad de argumentos por nombre
mostrar_informacion(nombre="Python", creador="Guido van Rossum", año=1991)
# Imprime:
# nombre: Python
# creador: Guido van Rossum
# año: 1991
El parámetro **datos
recibe todos los argumentos por nombre como un diccionario.
Ejemplo práctico: Función para formatear texto
Veamos un ejemplo que combina varios tipos de parámetros para crear una función flexible:
def formatear_texto(texto, mayusculas=False, prefijo="", sufijo="", separador=" "):
# Aplicar mayúsculas si se solicita
if mayusculas:
texto = texto.upper()
# Dividir el texto en palabras
palabras = texto.split()
# Aplicar prefijo y sufijo a cada palabra
palabras_formateadas = [f"{prefijo}{palabra}{sufijo}" for palabra in palabras]
# Unir las palabras con el separador especificado
resultado = separador.join(palabras_formateadas)
return resultado
# Ejemplos de uso
texto_original = "python es un lenguaje versátil"
# Uso básico sin modificaciones
print(formatear_texto(texto_original))
# Imprime: python es un lenguaje versátil
# Convertir a mayúsculas
print(formatear_texto(texto_original, mayusculas=True))
# Imprime: PYTHON ES UN LENGUAJE VERSÁTIL
# Añadir prefijo y sufijo
print(formatear_texto(texto_original, prefijo="«", sufijo="»"))
# Imprime: «python» «es» «un» «lenguaje» «versátil»
# Cambiar el separador
print(formatear_texto(texto_original, separador="-"))
# Imprime: python-es-un-lenguaje-versátil
# Combinación de opciones
print(formatear_texto(
texto_original,
mayusculas=True,
prefijo="#",
sufijo="!",
separador="..."
))
# Imprime: #PYTHON!...#ES!...#UN!...#LENGUAJE!...#VERSÁTIL!
Esta función demuestra cómo los parámetros y argumentos nos permiten crear herramientas flexibles que pueden adaptarse a diferentes necesidades sin tener que escribir código redundante.
Return
El valor de retorno es uno de los conceptos más importantes en las funciones de Python. Mientras que los parámetros permiten enviar información a una función, la sentencia return
nos permite obtener resultados de ella. Podemos pensar en las funciones como pequeñas fábricas que reciben materias primas (parámetros), las procesan, y nos devuelven un producto terminado (valor de retorno).
La sentencia return
cumple dos propósitos fundamentales:
- Devolver un valor como resultado de la función
- Finalizar la ejecución de la función inmediatamente
def calcular_cuadrado(numero):
resultado = numero * numero
return resultado # Devuelve el valor y termina la función
area = calcular_cuadrado(4)
print(area) # Imprime: 16
En este ejemplo, la función calcular_cuadrado
recibe un número, calcula su cuadrado y lo devuelve mediante return
. El valor devuelto se puede asignar a una variable (area
) para usarlo posteriormente.
Funciones sin return
Si una función no incluye una sentencia return
explícita, Python automáticamente devuelve None
:
def saludar(nombre):
print(f"Hola, {nombre}")
# No hay return explícito
resultado = saludar("Laura")
print(f"La función devolvió: {resultado}") # Imprime: La función devolvió: None
Esto muestra una distinción importante: la función saludar
muestra un mensaje pero no devuelve ningún valor utilizable. Esto es adecuado para funciones que realizan acciones (como imprimir o guardar datos) pero no necesitan proporcionar un resultado.
Retornando múltiples valores
Una característica poderosa de Python es la capacidad de devolver múltiples valores desde una función:
def estadisticas(numeros):
total = sum(numeros)
promedio = total / len(numeros)
minimo = min(numeros)
maximo = max(numeros)
return total, promedio, minimo, maximo
datos = [4, 8, 15, 16, 23, 42]
suma, media, menor, mayor = estadisticas(datos)
print(f"Suma: {suma}") # Imprime: Suma: 108
print(f"Promedio: {media}") # Imprime: Promedio: 18.0
print(f"Mínimo: {menor}") # Imprime: Mínimo: 4
print(f"Máximo: {mayor}") # Imprime: Máximo: 42
Técnicamente, Python empaqueta estos valores en una tupla que luego podemos desempaquetar en variables individuales. También podemos capturar el resultado como una única variable:
resultado = estadisticas(datos)
print(type(resultado)) # Imprime: <class 'tuple'>
print(resultado) # Imprime: (108, 18.0, 4, 42)
print(resultado[1]) # Imprime: 18.0 (accediendo al promedio)
Return anticipado
La sentencia return
finaliza inmediatamente la ejecución de la función. Esto es útil para crear salidas anticipadas cuando se cumplen ciertas condiciones:
def dividir_seguro(a, b):
# Verificación de seguridad
if b == 0:
print("Error: División por cero")
return None # Salida anticipada
# Este código solo se ejecuta si b no es cero
resultado = a / b
return resultado
print(dividir_seguro(10, 2)) # Imprime: 5.0
print(dividir_seguro(10, 0)) # Imprime: Error: División por cero y luego None
Esta técnica de retorno anticipado es muy útil para validaciones y manejo de casos especiales, ya que evita el anidamiento excesivo de bloques condicionales.
Patrones comunes con return
Función booleana (predicado)
Las funciones que devuelven True
o False
son extremadamente útiles para expresar condiciones de forma clara:
def es_mayor_de_edad(edad):
return edad >= 18
def es_correo_valido(email):
return "@" in email and "." in email
# Uso en condicionales
usuario_edad = 16
if es_mayor_de_edad(usuario_edad):
print("Acceso permitido")
else:
print("Acceso denegado") # Imprime: Acceso denegado
Transformación de datos
Las funciones que transforman datos de un formato a otro son muy comunes:
def formato_nombre(nombre, apellido):
return f"{apellido.upper()}, {nombre.capitalize()}"
print(formato_nombre("ana", "garcía")) # Imprime: GARCÍA, Ana
Cálculos y procesamiento
Las funciones que realizan cálculos y devuelven resultados son la base de muchos programas:
def calcular_precio_con_iva(precio_base, tasa_iva=0.21):
return precio_base * (1 + tasa_iva)
precio_final = calcular_precio_con_iva(100)
print(f"Precio con IVA: {precio_final} €") # Imprime: Precio con IVA: 121.0 €
Return con estructuras de datos
Las funciones pueden devolver estructuras de datos complejas como listas, diccionarios o incluso funciones:
def crear_lista_pares(maximo):
return [num for num in range(2, maximo + 1, 2)]
def crear_diccionario_cuadrados(numeros):
return {num: num ** 2 for num in numeros}
pares = crear_lista_pares(10)
print(pares) # Imprime: [2, 4, 6, 8, 10]
cuadrados = crear_diccionario_cuadrados([1, 2, 3, 4])
print(cuadrados) # Imprime: {1: 1, 2: 4, 3: 9, 4: 16}
Buenas prácticas con return
- Coherencia en los tipos de retorno: Es recomendable que una función devuelva siempre el mismo tipo de datos, o tipos compatibles.
# Enfoque mejorado: siempre devuelve una lista (vacía en caso de error)
def filtrar_positivos(numeros):
if not isinstance(numeros, list):
return [] # Lista vacía en caso de error
return [num for num in numeros if num > 0]
- Documentar el valor de retorno: Es importante que quede claro qué devuelve la función.
def calcular_descuento(precio, porcentaje):
"""
Calcula el precio con descuento.
Args:
precio: El precio original
porcentaje: El porcentaje de descuento (0-100)
Returns:
float: El precio después de aplicar el descuento
"""
return precio - (precio * porcentaje / 100)
- Evitar efectos secundarios: Las funciones que devuelven valores no deberían, idealmente, modificar el estado global o realizar acciones como imprimir.
# Mejor: separar la obtención del resultado de su presentación
def calcular_promedio(numeros):
return sum(numeros) / len(numeros)
# Uso
notas = [7, 8, 6, 9]
promedio = calcular_promedio(notas)
print(f"El promedio es: {promedio}") # La impresión se hace fuera de la función
- Usar return temprano para casos especiales: Esto mejora la legibilidad del código.
def obtener_calificacion(puntuacion):
if puntuacion < 0 or puntuacion > 100:
return "Puntuación inválida"
if puntuacion >= 90:
return "Sobresaliente"
if puntuacion >= 70:
return "Notable"
if puntuacion >= 60:
return "Bien"
if puntuacion >= 50:
return "Suficiente"
return "Insuficiente"
Ejemplo práctico: Función de conversión de temperatura
Veamos un ejemplo completo que ilustra el uso efectivo de return
:
def convertir_temperatura(valor, origen, destino):
"""
Convierte una temperatura entre diferentes unidades.
Args:
valor: El valor de la temperatura a convertir
origen: Unidad de origen ('C', 'F' o 'K')
destino: Unidad de destino ('C', 'F' o 'K')
Returns:
float: La temperatura convertida, o None si los parámetros son inválidos
"""
# Validación de parámetros
unidades_validas = {'C', 'F', 'K'}
if origen not in unidades_validas or destino not in unidades_validas:
return None
# Si origen y destino son iguales, no hay conversión necesaria
if origen == destino:
return valor
# Primero convertimos a Celsius como unidad intermedia
if origen == 'F':
celsius = (valor - 32) * 5/9
elif origen == 'K':
celsius = valor - 273.15
else: # origen es 'C'
celsius = valor
# Luego convertimos de Celsius a la unidad de destino
if destino == 'F':
return celsius * 9/5 + 32
elif destino == 'K':
return celsius + 273.15
else: # destino es 'C'
return celsius
# Ejemplos de uso
print(convertir_temperatura(25, 'C', 'F')) # Imprime: 77.0
print(convertir_temperatura(98.6, 'F', 'C')) # Imprime: 37.0
print(convertir_temperatura(0, 'C', 'K')) # Imprime: 273.15
print(convertir_temperatura(20, 'X', 'Y')) # Imprime: None
Esta función demuestra varias buenas prácticas:
- Validación de parámetros con retorno anticipado
- Manejo de casos especiales (cuando origen y destino son iguales)
- Documentación clara del valor de retorno
- Coherencia en el tipo de retorno (siempre devuelve un número o None)
El uso efectivo de return
es fundamental para crear funciones que no solo realicen tareas, sino que también proporcionen resultados útiles que podamos utilizar en otras partes de nuestro programa.
Docstrings
Los docstrings son cadenas de documentación que se utilizan en Python para describir qué hace una función, cómo usarla y qué esperar de ella. A diferencia de los comentarios regulares, los docstrings están diseñados para ser accesibles durante la ejecución del programa, lo que los convierte en una herramienta fundamental para crear código autodocumentado.
Un docstring se coloca justo después de la definición de una función, antes de cualquier otro código, y se escribe entre triples comillas (simples o dobles):
def sumar(a, b):
"""Suma dos números y devuelve el resultado."""
return a + b
Esta simple línea de documentación ya proporciona información valiosa sobre el propósito de la función. Los docstrings bien escritos hacen que tu código sea más accesible tanto para otros desarrolladores como para ti mismo cuando revisites el código en el futuro.
Estructura básica de un docstring
Aunque Python no impone un formato específico para los docstrings, existen convenciones ampliamente aceptadas. Un docstring completo suele incluir:
- Una breve descripción de una línea
- Una descripción más detallada (opcional)
- Información sobre los parámetros
- Información sobre el valor de retorno
- Ejemplos o notas (opcional)
def calcular_promedio(numeros):
"""
Calcula el promedio de una lista de números.
Suma todos los números de la lista y divide el resultado
entre la cantidad de elementos.
Args:
numeros: Una lista de valores numéricos
Returns:
El promedio como valor flotante
Ejemplo:
>>> calcular_promedio([1, 2, 3, 4])
2.5
"""
return sum(numeros) / len(numeros)
Accediendo a los docstrings
Una característica poderosa de los docstrings es que están disponibles en tiempo de ejecución a través del atributo __doc__
o la función help()
:
# Acceder al docstring directamente
print(calcular_promedio.__doc__)
# O usar la función help
help(calcular_promedio)
Esto permite que herramientas como el intérprete interactivo de Python, editores de código y generadores de documentación automática puedan mostrar esta información al programador.
Estilos de docstrings
Existen varios estilos populares para formatear docstrings. Los más comunes son:
Estilo Google
def validar_email(email):
"""
Verifica si una dirección de correo electrónico tiene formato válido.
Args:
email (str): La dirección de correo a validar
Returns:
bool: True si el formato es válido, False en caso contrario
Raises:
TypeError: Si email no es una cadena de texto
"""
if not isinstance(email, str):
raise TypeError("El email debe ser una cadena de texto")
return "@" in email and "." in email.split("@")[-1]
Estilo reStructuredText (reST)
def convertir_a_celsius(fahrenheit):
"""
Convierte una temperatura de Fahrenheit a Celsius.
:param fahrenheit: Temperatura en grados Fahrenheit
:type fahrenheit: float
:return: Temperatura en grados Celsius
:rtype: float
"""
return (fahrenheit - 32) * 5/9
Estilo NumPy/SciPy
def filtrar_pares(lista):
"""
Filtra los números pares de una lista.
Parameters
----------
lista : list
Lista de números enteros
Returns
-------
list
Nueva lista que contiene solo los números pares
"""
return [num for num in lista if num % 2 == 0]
Para proyectos personales o pequeños, puedes elegir el estilo que prefieras. Para proyectos más grandes o equipos, es recomendable seguir un estilo consistente en todo el código.
Docstrings para funciones simples
Para funciones muy sencillas, un docstring de una sola línea puede ser suficiente:
def es_mayor_de_edad(edad):
"""Determina si una persona es mayor de edad (18 años o más)."""
return edad >= 18
Sin embargo, incluso para funciones simples, un docstring más completo puede ser valioso:
def es_mayor_de_edad(edad):
"""
Determina si una persona es mayor de edad.
Args:
edad: Edad de la persona en años
Returns:
True si la edad es 18 o mayor, False en caso contrario
"""
return edad >= 18
Docstrings para funciones con comportamiento especial
Es especialmente útil documentar comportamientos especiales o casos límite:
def dividir_seguro(a, b):
"""
Realiza una división segura entre dos números.
Args:
a: El numerador
b: El denominador
Returns:
El resultado de la división a/b, o None si b es cero
Ejemplo:
>>> dividir_seguro(10, 2)
5.0
>>> dividir_seguro(10, 0)
None
"""
if b == 0:
return None
return a / b
Herramientas para trabajar con docstrings
Python incluye varias herramientas que aprovechan los docstrings:
- help(): Muestra la documentación de un objeto
- pydoc: Módulo que genera documentación a partir de docstrings
- doctest: Permite ejecutar ejemplos incluidos en los docstrings como pruebas
def area_triangulo(base, altura):
"""
Calcula el área de un triángulo.
Args:
base: Longitud de la base del triángulo
altura: Altura del triángulo
Returns:
El área del triángulo
Ejemplos:
>>> area_triangulo(4, 3)
6.0
>>> area_triangulo(5, 8)
20.0
"""
return (base * altura) / 2
Estos ejemplos no solo documentan cómo usar la función, sino que también pueden ejecutarse como pruebas automáticas con el módulo doctest
:
import doctest
doctest.testmod() # Ejecuta todos los ejemplos en los docstrings como pruebas
Buenas prácticas para escribir docstrings
- Sé conciso pero completo: Incluye toda la información necesaria sin ser excesivamente detallado.
def generar_contraseña(longitud=8):
"""
Genera una contraseña aleatoria.
Args:
longitud: Número de caracteres de la contraseña (predeterminado: 8)
Returns:
Una cadena con la contraseña generada
"""
import random
import string
caracteres = string.ascii_letters + string.digits + string.punctuation
return ''.join(random.choice(caracteres) for _ in range(longitud))
- Usa verbos en presente: Describe lo que la función hace, no lo que hará o hizo.
# Bien
def validar_usuario(nombre):
"""Verifica si el nombre de usuario cumple con los requisitos."""
# Evitar
def validar_usuario(nombre):
"""Esta función verificará si el nombre de usuario cumple con los requisitos."""
- Documenta los tipos de datos: Especifica qué tipos de datos espera la función y qué tipo devuelve.
def contar_palabras(texto):
"""
Cuenta el número de palabras en un texto.
Args:
texto (str): El texto a analizar
Returns:
int: El número de palabras encontradas
"""
return len(texto.split())
- Incluye ejemplos prácticos: Los ejemplos ayudan a entender rápidamente cómo usar la función.
def formatear_nombre(nombre, apellido):
"""
Formatea un nombre completo en formato "Apellido, Nombre".
Args:
nombre: Nombre de la persona
apellido: Apellido de la persona
Returns:
Cadena formateada como "Apellido, Nombre"
Ejemplo:
>>> formatear_nombre("Juan", "Pérez")
'Pérez, Juan'
"""
return f"{apellido}, {nombre}"
- Documenta excepciones: Si tu función puede lanzar excepciones, indícalo en el docstring.
def obtener_elemento(lista, indice):
"""
Obtiene un elemento de una lista por su índice.
Args:
lista: La lista de elementos
indice: Posición del elemento a obtener (comienza en 0)
Returns:
El elemento en la posición especificada
Raises:
IndexError: Si el índice está fuera del rango de la lista
"""
return lista[indice]
Ejemplo práctico: Función con docstring completo
Veamos un ejemplo completo que incorpora todas las buenas prácticas:
def calcular_precio_final(precio_base, descuento=0, impuesto=0.21):
"""
Calcula el precio final de un producto aplicando descuento e impuesto.
Primero aplica el descuento sobre el precio base y luego
añade el impuesto sobre el precio con descuento.
Args:
precio_base (float): Precio original del producto
descuento (float, opcional): Porcentaje de descuento (0-100). Predeterminado: 0
impuesto (float, opcional): Tasa de impuesto (0-1). Predeterminado: 0.21
Returns:
float: Precio final después de aplicar descuento e impuesto
Raises:
ValueError: Si alguno de los parámetros tiene un valor negativo
Ejemplos:
>>> calcular_precio_final(100)
121.0
>>> calcular_precio_final(100, 10)
108.9
>>> calcular_precio_final(100, 10, 0.1)
99.0
"""
if precio_base < 0 or descuento < 0 or impuesto < 0:
raise ValueError("Los valores no pueden ser negativos")
precio_con_descuento = precio_base * (1 - descuento/100)
precio_final = precio_con_descuento * (1 + impuesto)
return precio_final
Este docstring proporciona toda la información necesaria para usar la función correctamente:
- Qué hace la función
- Cómo funciona
- Qué parámetros acepta y sus tipos
- Valores predeterminados
- Qué devuelve
- Posibles errores
- Ejemplos de uso
Conclusión práctica
Los docstrings son una inversión en la calidad y mantenibilidad de tu código. Aunque escribir buenos docstrings requiere un esfuerzo adicional, este esfuerzo se compensa con creces cuando:
- Otros desarrolladores necesitan usar tus funciones
- Tú mismo necesitas recordar cómo funciona tu código después de un tiempo
- Quieres generar documentación automática para tu proyecto
- Deseas incluir pruebas integradas en tu código
Recuerda que un buen docstring debe responder las preguntas: ¿qué hace esta función?, ¿qué necesita para funcionar? y ¿qué produce como resultado? Si tu documentación responde claramente estas preguntas, estarás creando código más accesible y fácil de mantener.
Otros ejercicios de programación de Python
Evalúa tus conocimientos de esta lección Funciones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Módulo math
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
Todas las lecciones de Python
Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Python
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender qué es una función y cómo definirla en Python.
- Diferenciar entre parámetros y argumentos, y conocer los tipos de parámetros.
- Aprender a utilizar la sentencia return para devolver valores y finalizar funciones.
- Conocer la importancia y estructura de los docstrings para documentar funciones.
- Aplicar buenas prácticas en la creación y documentación de funciones para mejorar la legibilidad y mantenimiento del código.