Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

227
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!