• Saltar al contenido principal
  • Skip to secondary menu
  • Saltar a la barra lateral principal
  • Saltar al pie de página
  • Inicio
  • Secciones
    • Ciencia de datos
    • Criptografía
    • Herramientas
    • Machine Learning
    • Noticias
    • Opinión
    • Productividad
    • Programación
      • JavaScript
      • Julia
      • Matlab
      • Python
      • R
  • Programación
    • JavaScript
    • Julia
    • Matlab
    • Python
    • R
  • Laboratorio
    • Estadística
      • Calculadora del Tamaño Muestral en Encuestas
      • Calculadora de estadísticos descriptivos
      • Test de normalidad
      • Calculadora de contrastes de hipotesis
      • Calculadora de tamano del efecto
      • Simulador de Regresión Lineal con Ruido
      • Visualizador de PCA
      • Visualizador de Series Temporales
      • Simulador de Regresión Logística
      • Simulador de K-Means
      • Simulador de DBSCAN
      • Detector de la Ley de Benford
    • Probabilidad
      • Calculadora de Probabilidad de Distribuciones
      • Calculadora de Probabilidades de Lotería
      • Simulador del Problema de Monty Hall
      • Simulador de la Estrategia Martingala
    • Finanzas
      • Calculadora de Préstamos e Hipotecas
      • Conversor TIN ↔ TAE
      • Calculadora DCA con ajuste por inflación
      • Calculadora XIRR con Flujos Irregulares
      • Simulador FIRE (Financial Independence, Retire Early)
    • Negocios
      • CLV
      • Scoring
    • Herramientas
      • Formateador / Minificador de JSON
      • Conversor CSV ↔ JSON
      • Comparador y Formateador de Texto y JSON
      • Formateador y Tester de Expresiones Regulares
      • Inspector de JWT
      • Generador y verificador de hashes
      • Codificador / Decodificador Base64 y URL
      • Conversor de bases numericas
      • Conversor de Timestamp Unix
      • Conversor de colores
      • Generador de UUIDs
    • Juegos
      • Tres en Raya
      • Nim con Q-Learning
    • Más
      • Método D’Hondt
      • Generador de Contraseñas Seguras
  • Noticias
  • Boletín
  • Contacto
  • Tienda
    • Libros
    • Equipamiento de oficina
    • Equipamiento en movilidad

Analytics Lane

Ciencia e ingeniería de datos aplicada

  • Ciencia de datos
  • Machine Learning
  • IA Generativa
  • Python
  • Pandas
  • NumPy
  • R
  • Excel

Decoradores en Python: Qué son, cómo crear uno y ejemplos

septiembre 23, 2024 Por Daniel Rodríguez Deja un comentario
Tiempo de lectura: 7 minutos

Python es un lenguaje de programación que destaca por su simplicidad, flexibilidad y con el que es fácil escribir código limpio. Siendo los decoradores una de las características del lenguaje que más ayudan a esto. Los decoradores permiten extender el comportamiento de las funciones y métodos de una manera elegante, facilitando la reutilización del código. En esta entrada, se explorará qué son los decoradores en Python, cómo se pueden crear decoradores personalizados y las ventajas de su uso, incluyendo ejemplos con los que ilustrar su utilidad.

Tabla de contenidos

  • 1 ¿Qué son los decoradores en Python?
    • 1.1 Sintaxis básica de un decorador
    • 1.2 Decoradores anidados
  • 2 Ventajas de usar decoradores
  • 3 Casos de uso de los decoradores en Python
    • 3.1 Caso 1: Decoradores para medir el tiempo de ejecución
    • 3.2 Caso 2: Decoradores para crear un registro
    • 3.3 Caso 3: Decoradores para el controlar el acceso
    • 3.4 Caso 4: Decoradores para reintentar operaciones
  • 4 Conclusiones

¿Qué son los decoradores en Python?

En Python, un decorador es una función que recibe otra función como argumento, modifica su comportamiento y devuelve una nueva función. Permitiendo de este modo inyectar código antes o después de llamar a la función original. Los decoradores se utilizan habitualmente para realizar tareas de autenticación, validación, modificación del flujo de control, depuración o administración de recursos, entre otras.

Sintaxis básica de un decorador

La sintaxis básica para aplicar un decorador a una función es utilizando el símbolo @ seguido del nombre del decorador justo antes de la definición de la función. En el siguiente código se muestra un ejemplo básico:

def mi_decorador(func):
    def nueva_funcion():
        print("Algo se ejecuta antes de la función principal")
        func()
        print("Algo se ejecuta después de la función principal")
    return nueva_funcion


@mi_decorador
def funcion_principal():
    print("Esta es la función principal")

    
funcion_principal()

En este caso, al llamar a funcion_principal() se mostrará por pantalla tanto los mensajes del decorador como los de la función. El resultado de ejecutar el código será:

Nuevo test de normalidad interactivo en el laboratorio de Analytics Lane
En Analytics Lane
Nuevo test de normalidad interactivo en el laboratorio de Analytics Lane

Algo se ejecuta antes de la función principal
Esta es la función principal
Algo se ejecuta después de la función principal

Básicamente lo que se ha implementado en este ejemplo es:

  1. Definición del decorador: mi_decorador es una función que toma una función como argumento (func). En su código, se define y retorna una nueva función (nueva_funcion) basada en la función que se recibe como argumento.
  2. Aplicación del decorador: La línea @mi_decorador antes de la definición de funcion_principal indica que el decorador se debe aplicar a la función. Esto hace que en el código funcion_principal sea realmente nueva_funcion.
  3. Ejecución: Ahora, cuando se llama a funcion_principal(), en realidad se está llamando a nueva_funcion. La cual primero imprime el primer mensaje, llama a la función original func() y finalmente imprime otro mensaje.

Publicidad


Decoradores anidados

Los decoradores se pueden anidar, esto es, se puede aplicar más de un decorador a la misma función. Aplicándose los decoradores de manera envolvente, es decir, el último decorador aplicado será el primero en ejecutarse. Esto es lo que se muestra en el siguiente código de ejemplo.

def decorador_1(func):
    def nueva_funcion_1():
        print("Decorador 1 antes")
        func()
        print("Decorador 1 después")
    return nueva_funcion_1


def decorador_2(func):
    def nueva_funcion_2():
        print("Decorador 2 antes")
        func()
        print("Decorador 2 después")
    return nueva_funcion_2


@decorador_1
@decorador_2
def funcion_principal():
    print("Función principal")

    
funcion_principal()

El resultado será:

Decorador 1 antes
Decorador 2 antes
Función principal
Decorador 2 después
Decorador 1 después

Como se puede ver en la salida, primero se aplica decorador_2 , el último decorador, y sobre la función que devuelve este el decorador_1.

Ventajas de usar decoradores

El uso de decoradores en Python ofrece múltiples ventajas, especialmente cuando se desea escribir código limpio y reutilizable. A continuación, se detallan algunas de las principales ventajas:

  1. Reutilización del código: Los decoradores permiten encapsular funcionalidades comunes que pueden ser reutilizadas en múltiples funciones. Esto evita la repetición de código y hace que el mantenimiento sea más sencillo.
  2. Separación de responsabilidades: Al utilizar decoradores, se puede mantener el código de la función principal limpio y enfocado en su tarea específica. Lo que hace el código más limpio y fácil de mantener. El código relacionado con otras responsabilidades, como la validación de entradas o la gestión de recursos, se pueden manejarse externamente a través de decoradores.
  3. Modificación de comportamiento: Los decoradores permiten modificar el comportamiento de una función sin cambiar su código fuente. Esto es útil a la hora de añadir funcionalidades como una caché, autenticación o el registro de eventos.
  4. Legibilidad: La sintaxis de los decoradores es clara y explícita. Cuando se escribe @decorador encima de una función, se sabe que se está aplicando una transformación o añadido a esa función, lo cual mejora la legibilidad del código.
  5. Manejo de tareas comunes: Los decoradores pueden realizar tareas comunes de manera centralizada, como medir el tiempo de ejecución, manejo de excepciones o la autenticación de usuarios, asegurando que todas las funciones decoradas compartan estas características.

Casos de uso de los decoradores en Python

Una vez que se comprende que son los decoradores y algunas de sus ventajas, se pueden ver algunos casos prácticos de estos a modo de ejemplo.

Publicidad


Caso 1: Decoradores para medir el tiempo de ejecución

Uno de los usos más habituales de los decoradores es medir el tiempo de ejecución de una función. Algo especialmente útil durante la optimización de código, donde es necesario identificar qué partes del código están tardando más tiempo en ejecutarse.

import time


def medir_tiempo(func):
    def wrapper(*args, **kwargs):
        inicio = time.time()  # Capturar el tiempo de inicio
        resultado = func(*args, **kwargs)  # Ejecutar la función original
        fin = time.time()  # Capturar el tiempo al finalizar
        print(f"Tiempo de ejecución: {fin - inicio:.4f} segundos")
        return resultado
    return wrapper


@medir_tiempo
def funcion_lenta():
    time.sleep(2)  # Simular una función que tarda 2 segundos en ejecutarse
    print("Función lenta ejecutada")

    
funcion_lenta()

En el decorador medir_tiempo la función wrapper toma cualquier número de argumentos (*args, **kwargs), lo que permite decorar funciones con diferentes firmas. Dentro del decorador se usa time.time() para obtener el tiempo antes y después de la ejecución de la función. La diferencia entre ambos valores, el tiempo transcurrido, se imprime en segundos con cuatro decimales.

El resultado al ejecutar funcion_lenta() será algo como:

Función lenta ejecutada
Tiempo de ejecución: 2.0055 segundos

Caso 2: Decoradores para crear un registro

Otro caso de uso especialmente útil de los decoradores es la creación de un registro de las llamadas a una función. Lo que permite realizar una auditoría o depuración de los programas. A continuación, se muestra un ejemplo de este caso.

def registrar_accion(func):
    def wrapper(*args, **kwargs):
        print(f"Llamando a {func.__name__} con {args} y {kwargs}")
        resultado = func(*args, **kwargs)
        print(f"{func.__name__} terminó de ejecutarse")
        return resultado
    return wrapper


@registrar_accion
def sumar(a, b):
    return a + b


@registrar_accion
def saludar(nombre):
    print(f"Hola, {nombre}!")

    
suma = sumar(3, 5)
saludar("Juan")

El decorador registrar_accion envuelve la función original e imprime un mensaje antes y después de su ejecución, mostrando el nombre de la función y sus argumentos. Unos registros extremadamente útiles para monitorear y depurar aplicaciones.

La salida del código será:

Llamando a sumar con (3, 5) y {}
sumar terminó de ejecutarse
Llamando a saludar con ('Juan',) y {}
Hola, Juan!
saludar terminó de ejecutarse

Caso 3: Decoradores para el controlar el acceso

En aplicaciones más complejas, a menudo es necesario controlar el acceso a ciertas funciones o métodos, especialmente en aplicaciones web o sistemas con múltiples usuarios. Verificar si un usuario tiene los permisos adecuados antes de permitir la ejecución de una función es algo que se puede hacer fácilmente con decoradores.

def verificar_acceso(func):
    def wrapper(usuario, *args, **kwargs):
        if usuario != "admin":
            print("Acceso denegado")
            return
        return func(usuario, *args, **kwargs)
    return wrapper


@verificar_acceso
def cambiar_configuracion(usuario, nueva_configuracion):
    print(f"Configuración cambiada a {nueva_configuracion}")

    
cambiar_configuracion("admin", "Modo oscuro")
cambiar_configuracion("invitado", "Modo claro")

Este decorador verificar_acceso comprueba si el usuario tiene permisos para ejecutar la función. Si el usuario no es “admin”, el acceso es denegado y la función no se ejecuta. Este tipo de decorador es fundamental en aplicaciones que requieren control de acceso y permisos.

La salida del código será:

Configuración cambiada a Modo oscuro
Acceso denegado

Indicando que solo la primera llamada se ha ejecutado, mientras que en la segunda se ha denegado el acceso.

Publicidad


Caso 4: Decoradores para reintentar operaciones

Los decoradores también pueden recibir parámetros, lo que permite modificar su comportamiento. Permitiendo modificar el comportamiento del decorador en cada caso. Algo que puede ser interesante, por ejemplo, cuando se desea reintentar la ejecución de una función cuando esta falla debido a una excepción, permitiendo cambiar el número de reintentos. En el siguiente ejemplo, se puede ver la implementación de un decorador parametrizado para controlar el número de reintentos:

def reintentar(veces):
    def decorador(func):
        def wrapper(*args, **kwargs):
            for _ in range(veces):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"Error: {e}. Reintentando...")
            print(f"Operación fallida después de {veces} intentos")
        return wrapper
    return decorador


@reintentar(3)
def division(a, b):
    return a / b


print(division(10, 2))
print(division(10, 0))

El decorador reintentar toma un argumento veces, que determina cuántas veces debe reintentar la ejecución de la función decorada en caso de fallo. Si la función lanza una excepción, se reintentará el número de veces especificado.

La salida del código será:

5.0
Error: division by zero. Reintentando...
Error: division by zero. Reintentando...
Error: division by zero. Reintentando...
Operación fallida después de 3 intentos
None

Conclusiones

Los decoradores en Python son una herramienta extremadamente útil para escribir código limpio, eficiente y mantenible. Al permitir modificar o extender el comportamiento de las funciones de manera elegante, los decoradores facilitan la reutilización del código y la separación de responsabilidades. La capacidad de crear decoradores personalizados permite adaptar las soluciones a las necesidades específicas de cada proyecto, haciendo que el código sea más flexible y robusto.

Imagen de Mariya en Pixabay

¿Te ha parecido de utilidad el contenido?

¡Puntúalo entre una y cinco estrellas!

Puntuación promedio 0 / 5. Votos emitidos: 0

Ya que has encontrado útil este contenido...

¡Síguenos en redes sociales!

¡Siento que este contenido no te haya sido útil!

¡Déjame mejorar este contenido!

Dime, ¿cómo puedo mejorar este contenido?

Publicaciones relacionadas

  • Nuevo test de normalidad interactivo en el laboratorio de Analytics Lane
  • Nuevo conversor de timestamp Unix en el laboratorio de Analytics Lane
  • Calculadora de Contrastes de Hipótesis: interpreta correctamente el p-valor y toma decisiones estadísticas con confianza
  • Calculadora de Tamaño del Efecto: la herramienta clave para entender cuánto importa realmente una diferencia
  • Simulador de DBSCAN: descubre cómo encontrar clusters reales (y ruido) sin fijar K
  • Conversor de Colores: convierte, compara y valida cualquier color en tiempo real
  • Analytics Lane lanza su Generador de UUIDs: identificadores únicos, seguros y listos para producción en segundos
  • 1200 publicaciones en Analytics Lane
  • Analytics Lane lanza su Conversor TIN ↔ TAE: la herramienta definitiva para entender el coste real de depósitos, préstamos e hipotecas

Publicado en: Python

Interacciones con los lectores

Deja una respuesta Cancelar la respuesta

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

I accept the Terms and Conditions and the Privacy Policy

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Barra lateral principal

Suscríbete a nuestro boletín

Suscríbete al boletín semanal para estar al día de todas las publicaciones.

Política de Privacidad

Analytics Lane en redes sociales

  • Amazon
  • Bluesky
  • Facebook
  • GitHub
  • Instagram
  • Mastodon
  • Pinterest
  • RSS
  • Telegram
  • Tumblr
  • Twitter
  • YouTube

Publicidad

Entradas recientes

De la Regresión Logística al Scorecard: La Transformación Matemática

mayo 19, 2026 Por Daniel Rodríguez

Noticias

Analytics Lane lanza la versión 1.1 del laboratorio con nuevas suites de CLV y Scoring

mayo 18, 2026 Por Daniel Rodríguez

Interés compuesto: la fuerza que multiplica tu dinero (y los errores que la anulan)

mayo 14, 2026 Por Daniel Rodríguez

Publicidad

Es tendencia

  • Gráficos de correlación en Seaborn: Mapas de calor y gráficos de pares publicado el julio 27, 2023 | en Python
  • Curiosidad: El uso del número 42 para fijar la semilla publicado el julio 7, 2023 | en Opinión
  • Inteligencia artificial generativa en seguros: Cinco aplicaciones que están transformando la industria publicado el marzo 14, 2025 | en Ciencia de datos, Opinión
  • Buscar en Excel con dos o más criterios publicado el septiembre 7, 2022 | en Herramientas
  • pandas Pandas: Contar los valores nulos en DataFrame publicado el agosto 12, 2021 | en Python

Publicidad

Lo mejor valorado

4.9 (24)

Seleccionar filas y columnas en Pandas con iloc y loc

4.6 (16)

Archivos JSON con Python: lectura y escritura

4.4 (14)

Ordenación de diccionarios en Python mediante clave o valor

4.7 (13)

Operaciones de filtrado de DataFrame con Pandas en base a los valores de las columnas

4.9 (11)

Pandas: Cambiar los tipos de datos en los DataFrames

Comentarios recientes

  • bif en JSON en bases de datos: cuándo es buena idea y cuándo no
  • bif en Cómo desinstalar Oracle Database 19c en Windows
  • M. Pilar en Cómo eliminar las noticias en Windows 11 y recuperar tu concentración
  • Daniel Rodríguez en Probabilidad básica: cómo entender el azar en nuestra vida diaria
  • Pepe en Probabilidad básica: cómo entender el azar en nuestra vida diaria

Publicidad


Footer

Analytics Lane

  • Acerca de Analytics Lane
  • Boletín de noticias
  • Contacto
  • Libros
  • Lo más popular
  • Noticias
  • Tienda
  • Tiendas afiliadas

Secciones

  • Ciencia de datos
  • Criptografía
  • Herramientas
  • Machine Learning
  • Opinión
  • Productividad
  • Programación
  • Reseñas

Sobre de Analytics Lane

En Analytics Lane tratamos de explicar los principales conceptos de la ciencia e ingeniería de datos con un enfoque práctico. Los principales temas tratados son ciencia de datos, ingeniería de datos, inteligencia artificial, machine learning, deep learning y criptografía. Además, también se habla de los principales lenguajes de programación y herramientas utilizadas por los científicos e ingenieros de datos.

Copyright © 2018-2026 Analytics Lane ·Términos y condiciones ·Política de Cookies ·Política de Privacidad ·Herramientas de privacidad ·Contacto