Leggi il codice attentamente
from functools import wraps
attempts_log: list[str] = []
def retry(max_attempts: int = 3, base_delay: float = 0, retry_on: tuple = (Exception,)):
def decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
attempt = 0
while True:
attempt += 1
try:
return fn(*args, **kwargs)
except retry_on as e:
attempts_log.append(f"attempt {attempt} failed: {type(e).__name__}")
if attempt >= max_attempts:
attempts_log.append("giving up")
raise
# In real code: time.sleep(base_delay * (2 ** (attempt - 1)))
# Here we log the would-be sleep for the predict trace.
attempts_log.append(f"sleep {base_delay * (2 ** (attempt - 1))}")
return wrapper
return decorator
calls = [0]
@retry(max_attempts=4, base_delay=1, retry_on=(ValueError,))
def flaky() -> str:
calls[0] += 1
if calls[0] < 3:
raise ValueError(f"fail #{calls[0]}")
return "ok"
result = flaky()
print(f"result: {result}")
print(f"calls: {calls[0]}")
for line in attempts_log:
print(line)
Cosa stamperà il programma? Scrivi qui: