Verwenden Sie Python Decorators, um Codeblöcke erneut zu versuchen
-
Wichtigkeit von
Wiederholen
-Dekorateuren -
Verwenden Sie
@retry
, um Codeblöcke in Python erneut zu versuchen -
Verwenden Sie
tenacity
, um Codeblöcke in Python erneut zu versuchen
Wir können eine Funktion oder Klasse mit einem Decorator modifizieren, um das Verhalten der Funktion zu erweitern, ohne sie dauerhaft zu ändern. In diesem Artikel wird beschrieben, wie Sie retry
-Dekoratoren verwenden, um eine vorhandene Funktion zu ändern, ohne Änderungen an der besagten Funktion vorzunehmen.
In diesem Fall wiederholt die Modifikation die Funktion mehrmals in einer bestimmten Situation, in der ihr Rückgabewert von dem abweichen könnte, was wir wollen.
Wichtigkeit von Wiederholen
-Dekorateuren
Wir können Decorators verwenden, um das Verhalten einer bestimmten Funktion zu erweitern, und wir können ganz einfach Decorators erstellen, um diese Funktion zu ändern, selbst wenn wir keinen Zugriff darauf haben oder sie nicht ändern möchten.
Wir brauchen diese Funktion oft auf eine ziemlich spezifische Art und Weise, und hier kommen Python-Dekoratoren ins Spiel. Erstellen wir also eine einfache Funktion, um zu zeigen, wie Dekoratoren funktionieren.
Die einfache Funktion quotient()
nimmt zwei Argumente und dividiert das erste Argument durch das zweite Argument.
def quotient(a, b):
return a / b
print(quotient(3, 7))
Ausgang:
0.42857142857142855
Wenn wir jedoch möchten, dass das Divisionsergebnis immer so ist, dass die größere Zahl dividiert wird (das Ergebnis ist also 2.3333333333333335
), können wir entweder den Code ändern oder Dekoratoren
verwenden.
Mit Dekoratoren können wir das Verhalten der Funktion erweitern, ohne ihren Codeblock zu ändern.
def improv(func):
def inner(a, b):
if a < b:
a, b = b, a
return func(a, b)
return inner
@improv
def quotient(a, b):
return a / b
print(quotient(3, 7))
Ausgang:
2.3333333333333335
Die improv()
-Funktion ist die Decorator-Funktion, die die quotient()
-Funktion als Argument nimmt und eine innere Funktion enthält, die das Argument der quotient()
-Funktion nimmt und die zusätzliche Funktionalität einbringt, die Sie benötigen hinzufügen.
Mit Decorators können wir jetzt einer bestimmten Funktion eine Wiederholen
-Funktion hinzufügen, insbesondere bei Funktionen, auf die wir keinen Zugriff haben.
retry
-Decorators sind in Szenarien hilfreich, in denen unvorhersehbare Verhaltensweisen oder Fehler auftreten können und Sie dieselbe Operation erneut versuchen möchten, wenn sie auftreten.
Ein typisches Beispiel ist die Behandlung einer fehlgeschlagenen Anfrage innerhalb einer for
-Schleife. In solchen Szenarien können wir retry
-Decorators verwenden, um die Wiederholung dieser bestimmten Anfrage eine bestimmte Anzahl von Malen zu verwalten.
Verwenden Sie @retry
, um Codeblöcke in Python erneut zu versuchen
Für retry
-Decorators gibt es verschiedene Bibliotheken, die diese Funktion bereitstellen, und eine dieser Bibliotheken ist die retrying
-Bibliothek.
Damit können Sie Warten
- und Stopp
-Bedingungen von Ausnahmen
bis zu erwarteten Rückgabeergebnissen festlegen. Um die Bibliothek retrying
zu installieren, können wir den Befehl pip
wie folgt verwenden:
pip install retrying
Lassen Sie uns nun eine Funktion erstellen, die zufällig Zahlen zwischen 0
und 10
erstellt, aber einen ValueError
auslöst, wenn wir eine Situation haben, in der die Zahl größer als 1
ist.
import random
def generateRandomly():
if random.randint(0, 10) > 1:
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
Die Codeausgabe sieht wie folgt aus, wenn die zu diesem Zeitpunkt generierte Zahl größer als eins ist.
Traceback (most recent call last):
File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 11, in <module>
print(generateRandomly())
File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 6, in generateRandomly
raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one
Wir können keine Situation haben, in der ein ValueError
in unseren Code geworfen wird, also können wir einen retry
-Decorator einführen, um die Funktion generateRandomly()
erneut zu versuchen, bis sie keinen ValueError
auslöst.
import random
from retrying import retry
@retry
def generateRandomly():
if random.randint(0, 10) > 1:
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
Ausgang:
Finally Generated.
Jetzt wiederholt der retry
-Decorator die random
-Operation, bis es keinen ValueError
mehr gibt und wir nur die Zeichenfolge Finally Generated.
haben.
Wir können sehen, wie oft der Code generateRandomly()
wiederholt hat, indem wir eine print()
-Anweisung in den if
-Block einfügen.
import random
from retrying import retry
@retry
def generateRandomly():
if random.randint(0, 10) > 1:
print("1")
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
Ausgang:
1
1
1
1
1
1
1
Finally Generated.
Hier 8
, aber es könnte anders sein, wenn Sie den Code ausführen. Wir können jedoch keine Situation haben, in der der Code für eine lange Zeit wiederholt versucht. Wir haben also Argumente wie stop_max_attempt_number
und stop_max_delay
.
import random
from retrying import retry
@retry(stop_max_attempt_number=5)
def generateRandomly():
if random.randint(0, 10) > 1:
print("1")
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
Ausgang:
1
1
1
Finally Generated.
Die Funktion wird nur 5
Mal wiederholt, aber entweder ist sie vor dem fünften Mal erfolgreich, gibt den Wert Finally Generated.
zurück, oder sie tut es nicht und wirft den ValueError
.
1
1
1
1
1
File "C:\Python310\lib\site-packages\retrying.py", line 247, in get
six.reraise(self.value[0], self.value[1], self.value[2])
File "C:\Python310\lib\site-packages\six.py", line 719, in reraise
raise value
File "C:\Python310\lib\site-packages\retrying.py", line 200, in call
attempt = Attempt(fn(*args, **kwargs), attempt_number, False)
File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 9, in generateRandomly
raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one
Verwenden Sie tenacity
, um Codeblöcke in Python erneut zu versuchen
Die retrying
-Bibliothek kann etwas eigenartig sein und wird nicht mehr gepflegt, aber die tenacity
-Bibliothek bietet all ihre Funktionen mit mehr verfügbaren Tools.
Um tenacity
zu installieren, verwenden Sie den folgenden pip
-Befehl:
pip install tenacity
Wir können den gleichen Code mit einem stop
-Versuch bei 3
ausprobieren.
import random
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def generateRandomly():
if random.randint(0, 10) > 1:
print("1")
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
Die Ausgabe des Codes, wenn die generierte Zufallszahl innerhalb des Zeitrahmens von drei Versuchen kleiner als 1 ist.
1
Finally Generated.
Ist dies jedoch nicht der Fall, wird die folgende Ausgabe ausgegeben.
1
1
1
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 407, in __call__
result = fn(*args, **kwargs)
File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 9, in generateRandomly
raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one
The above exception was a direct cause of the following exception:
Traceback (most recent call last):
File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 14, in <module>
print(generateRandomly())
File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 324, in wrapped_f
return self(f, *args, **kw)
File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 404, in __call__
do = self.iter(retry_state=retry_state)
File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 361, in iter
raise retry_exc from fut.exception()
tenacity.RetryError: RetryError[<Future at 0x29a75442c20 state=finished raised ValueError>]
Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.
LinkedIn