Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

131
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda