das Problem konnte ich lösen, allerdings hoffe ich das mir jemand sagen kann, warum die Lösung funktioniert hat...

Der Decorator soll die Funktion bei einer Exception neu starten (gedacht für eine API Abfrage mit unzuverlässigen Servern).
Mit "retryonfail_broken" bekomme ich die Fehlermeldung:
Code: Alles auswählen
UnboundLocalError: local variable 'attempts' referenced before assignment
Code: Alles auswählen
loopcount = attempts

Wird
Code: Alles auswählen
attempts -= 1
Mich würde wirklich interessieren, ob jemand die Logik kennt die dahinter steckt und sie mir erklären kann.

Code: Alles auswählen
def retryonfail(attempts=5):
def multitry(func):
def connecttry(*args, **kwargs):
returnresults = None
successful = False
loopcount = attempts # <-- Ohne das funktioniert es nicht, aber warum?
while loopcount > 0:
try:
returnresults = func(*args, **kwargs)
successful = True
break
except Exception as e:
loopcount -= 1
if successful:
return returnresults
else:
raise Exception("Das war wohl nix")
return connecttry
return multitry
def retryonfail_broken(attempts=5):
def multitry(func):
def connecttry(*args, **kwargs):
returnresults = None
successful = False
while attempts > 0: # Hier kommt der UnboundLocalError. Aber nur, wenn weiter unten attempts -= 1 steht. Ansonsten kommt man in while rein.
try:
returnresults = func(*args, **kwargs)
successful = True
break
except Exception as e:
attempts -= 1 # <-- Ohne die Zeile wird "while" betreten und läuft weiter :shock:
if successful:
return returnresults
else:
raise Exception("Das war wohl nix")
return connecttry
return multitry
@retryonfail_broken(2)
def testme(text):
if text in "test":
print(text)
else:
raise ValueError("Fehlerteufel")
testme("test")