Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

132
Vistas
Obtener el nombre de la función cuando se usa ContextDecorator como decorador

Tengo el siguiente administrador de contexto y decorador para cronometrar cualquier función o bloque de código:

 import time from contextlib import ContextDecorator class timer(ContextDecorator): def __init__(self, label: str): self.label = label def __enter__(self): self.start_time = time.perf_counter() return self def __exit__(self, *exc): net_time = time.perf_counter() - self.start_time print(f"{self.label} took {net_time:.1f} seconds") return False

Puedes usarlo como un administrador de contexto:

 with timer("my code block"): time.sleep(2) # my code block took 2.0 seconds

También puedes usarlo como decorador:

 @timer("my_func") def my_func(): time.sleep(3) my_func() # my_func took 3.0 seconds

Lo único que no me gusta es tener que pasar manualmente el nombre de la función como label cuando se usa como decorador. Me encantaría que el decorador use automáticamente el nombre de la función si no se pasa ninguna etiqueta:

 @timer() def my_func(): time.sleep(3) my_func() # my_func took 3.0 seconds

¿Hay alguna manera de hacer esto?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Si también anula el __call__() heredado de la clase base ContextDecorator en su clase de timer y agrega un valor predeterminado único al inicializador para el argumento de la label , puede verificarlo y tomar el __name__ de la función cuando se llama:

 import time from contextlib import ContextDecorator class timer(ContextDecorator): def __init__(self, label: str=None): self.label = label def __call__(self, func): if self.label is None: # Label was not provided self.label = func.__name__ # Use function's name. return super().__call__(func) def __enter__(self): self.start_time = time.perf_counter() return self def __exit__(self, *exc): net_time = time.perf_counter() - self.start_time print(f"{self.label} took {net_time:.1f} seconds") return False @timer() def my_func(): time.sleep(3) my_func() # -> my_func took 3.0 seconds
over 4 years ago · Santiago Trujillo Denunciar

0

Según un examen de la fuente de ContextDecorator , no parece haber ninguna forma de que el nombre de la función envuelta pueda estar disponible para el administrador de contexto. En su lugar, puede crear su propia versión de ContextDecorator , anulando __call__

 import time import functools, contextlib class _ContextDecorator(contextlib.ContextDecorator): def __call__(self, func): self.f_name = func.__name__ @functools.wraps(func) def wrapper(*args, **kwargs): with self._recreate_cm(): return func(*args, **kwargs) return wrapper

Uso:

 class timer(_ContextDecorator): def __init__(self, label: str = None): self.f_name = label def __enter__(self): self.start_time = time.perf_counter() return self def __exit__(self, *exc): net_time = time.perf_counter() - self.start_time print(f"{self.f_name} took {net_time:.1f} seconds") return False with timer('my_func'): time.sleep(2) @timer() def my_func(): time.sleep(3) my_func()
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda