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

231
Vistas
Función de reintento en Python

Hace algún tiempo, necesitaba una función de retry en R para manejar la respuesta lenta de los servidores. La función tendría el siguiente comportamiento: (prueba una acción (función o método), y si falla, espera un poco y luego vuelve a intentarlo)x10

Se me ocurrió lo siguiente:

 retry <- function(fun, max_trys = 10, init = 0){ suppressWarnings(tryCatch({ Sys.sleep(0.3); if(init<max_trys) {fun} }, error=function(e){retry(fun, max_trys, init = init+1)}))}

Funcionó bien. Ahora necesito lo mismo en Python3, así que traté de hacer el mismo código:

 import time def retry_fun(fun, max_trys = 10, init=0): try: time.sleep(0.3) if(init<max_trys): fun except: retry_fun(fun, max_trys, init = init+1)

Pero cuando lo ejecuto, está bloqueando mi kernel. Como soy un poco principiante en Python, no estoy seguro de qué está causando el bloqueo, y si/cómo se puede pasar una función como argumento a otra función.

Podrías ayudarme ?

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

0

Además de poder pasar funciones y usarlas agregando () después del nombre (sintaxis de Python para invocar llamadas), no necesita usar la recursividad; solo ponlo en un bucle:

 import time def retry(fun, max_tries=10): for i in range(max_tries): try: time.sleep(0.3) fun() break except Exception: continue

except Exception debe cambiarse para capturar una excepción significativa que la función podría generar. El uso de Exception (como lo hice en el ejemplo) generalmente es una mala práctica, ya que detecta una gran clase de excepciones que es posible que no desee capturar.

Aparte de eso, es mejor usar un for-loop lugar de un tercer contador explícito y recursividad (que conduce a una pila de llamadas larga para valores grandes).

over 4 years ago · Santiago Trujillo Denunciar

0

Sé que esta es una vieja pregunta. Sin embargo, me gustaría agregar la solución que he preparado. La mejor manera es escribir un decorador de retry que lo vuelva a intentar cuando ocurra una excepción. Además, también puede establecer un retraso exponencial personalizado. El docstring explica cómo puede usar el decorador. Aquí tienes:

 import logging import time from functools import partial, wraps def retry(func=None, exception=Exception, n_tries=5, delay=5, backoff=1, logger=False): """Retry decorator with exponential backoff. Parameters ---------- func : typing.Callable, optional Callable on which the decorator is applied, by default None exception : Exception or tuple of Exceptions, optional Exception(s) that invoke retry, by default Exception n_tries : int, optional Number of tries before giving up, by default 5 delay : int, optional Initial delay between retries in seconds, by default 5 backoff : int, optional Backoff multiplier eg value of 2 will double the delay, by default 1 logger : bool, optional Option to log or print, by default False Returns ------- typing.Callable Decorated callable that calls itself when exception(s) occur. Examples -------- >>> import random >>> @retry(exception=Exception, n_tries=4) ... def test_random(text): ... x = random.random() ... if x < 0.5: ... raise Exception("Fail") ... else: ... print("Success: ", text) >>> test_random("It works!") """ if func is None: return partial( retry, exception=exception, n_tries=n_tries, delay=delay, backoff=backoff, logger=logger, ) @wraps(func) def wrapper(*args, **kwargs): ntries, ndelay = n_tries, delay while ntries > 1: try: return func(*args, **kwargs) except exception as e: msg = f"{str(e)}, Retrying in {ndelay} seconds..." if logger: logging.warning(msg) else: print(msg) time.sleep(ndelay) ntries -= 1 ndelay *= backoff return func(*args, **kwargs) return wrapper
over 4 years ago · Santiago Trujillo Denunciar

0

Hay un par de paquetes de Python:

  1. Apártate
  2. tenacidad

Ejemplo de retroceso

 import backoff @backoff.on_exception(backoff.expo, (MyPossibleException1, MyPossibleException2)) def your_function(param1, param2): # Do something

Ejemplo de tenacidad

 from tenacity import wait_exponential, retry, stop_after_attempt @retry(wait=wait_exponential(multiplier=2, min=2, max=30), stop=stop_after_attempt(5)) def your_function(param1, param2): # Do something
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