Python 데코레이터를 사용하여 코드 블록 재시도
데코레이터를 사용하여 함수나 클래스를 수정하여 영구적으로 변경하지 않고 함수의 동작을 확장할 수 있습니다. 이 기사에서는 재시도
데코레이터를 사용하여 해당 기능을 변경하지 않고 기존 기능을 수정하는 방법에 대해 설명합니다.
이 경우 수정은 반환 값이 우리가 원하는 것과 다를 수 있는 주어진 상황에서 함수를 여러 번 재시도합니다.
재시도
데코레이터의 중요성
데코레이터를 사용하여 특정 기능의 동작을 확장할 수 있으며 데코레이터를 쉽게 만들어 해당 기능에 액세스할 수 없거나 변경하고 싶지 않은 경우에도 해당 기능을 수정할 수 있습니다.
우리는 종종 그 함수가 다소 특정한 방식으로 필요할 수 있으며, 여기에서 Python 데코레이터가 필요합니다. 따라서 데코레이터가 작동하는 방식을 보여주는 간단한 함수를 만들어 봅시다.
간단한 함수 quotient()
는 두 개의 인수를 사용하고 첫 번째 인수를 두 번째 인수로 나눕니다.
def quotient(a, b):
return a / b
print(quotient(3, 7))
출력:
0.42857142857142855
그러나 나눗셈 결과가 항상 더 큰 숫자가 나눕니다(따라서 결과는 2.3333333333333335
)가 되도록 하려면 코드를 변경하거나 데코레이터
를 사용할 수 있습니다.
데코레이터를 사용하면 코드 블록을 변경하지 않고도 함수의 동작을 확장할 수 있습니다.
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))
출력:
2.3333333333333335
improv()
함수는 quotient()
함수를 인수로 사용하고 quotient()
함수의 인수를 취하는 내부 함수를 보유하고 필요한 추가 기능을 제공하는 데코레이터 함수입니다. 추가하다.
이제 데코레이터를 사용하여 특정 함수, 특히 액세스 권한이 없는 함수에 재시도
기능을 추가할 수 있습니다.
‘retry’ 데코레이터는 예측할 수 없는 동작이나 오류가 있을 수 있고 이러한 작업이 발생할 때 동일한 작업을 다시 시도하려는 시나리오에서 유용합니다.
일반적인 예는 for
루프 내에서 실패한 요청을 처리하는 것입니다. 이러한 시나리오에서는 재시도
데코레이터를 사용하여 특정 요청을 지정된 횟수만큼 재시도하도록 관리할 수 있습니다.
@retry
를 사용하여 Python에서 코드 블록 재시도
retry
데코레이터의 경우 이 기능을 제공하는 다양한 라이브러리가 있으며 이러한 라이브러리 중 하나가 retrying
라이브러리입니다.
이를 통해 예외
에서 예상 반환 결과까지 대기
및 중지
조건을 지정할 수 있습니다. 재시도
라이브러리를 설치하려면 다음과 같이 pip
명령을 사용할 수 있습니다.
pip install retrying
이제 0
과 10
사이의 숫자를 임의로 생성하지만 숫자가 1
보다 큰 상황이 있을 때 ValueError
를 발생시키는 함수를 만들어 보겠습니다.
import random
def generateRandomly():
if random.randint(0, 10) > 1:
raise ValueError("Number generated is greater than one")
else:
return "Finally Generated."
print(generateRandomly())
이때 생성된 숫자가 1보다 큰 경우 코드 출력은 다음과 같습니다.
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
코드에 ValueError
가 발생하는 상황이 있을 수 없으므로 retry
데코레이터를 도입하여 ValueError
가 발생하지 않을 때까지 generateRandomly()
함수를 재시도할 수 있습니다.
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())
출력:
Finally Generated.
이제 retry
데코레이터는 ValueError
가 없을 때까지 random
작업을 재시도하고 Finally Generated.
문자열만 갖게 됩니다.
if
블록 내에 print()
문을 도입하여 코드가 generateRandomly()
를 재시도한 횟수를 확인할 수 있습니다.
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())
출력:
1
1
1
1
1
1
1
Finally Generated.
여기서는 8
이지만 코드를 실행하면 다를 수 있습니다. 그러나 코드가 오랫동안 재시도를 계속하는 상황은 있을 수 없습니다. 따라서 stop_max_attempt_number
및 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())
출력:
1
1
1
Finally Generated.
함수는 5
번만 재시도되지만 다섯 번째 시도 전에 성공하거나 Finally Generated.
값을 반환하거나 그렇지 않고 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
끈기
를 사용하여 Python에서 코드 블록 재시도
재시도
라이브러리는 다소 기이할 수 있으며 더 이상 유지 관리되지 않지만 강인성
라이브러리는 모든 기능과 더 많은 도구를 일회용으로 제공합니다.
tenacity
를 설치하려면 다음 pip
명령을 사용하십시오.
pip install tenacity
3
에서 중지
시도로 동일한 코드를 시도할 수 있습니다.
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())
세 번의 시도 기간 내에 생성된 난수가 1 미만인 경우 코드의 출력입니다.
1
Finally Generated.
그러나 그렇지 않은 경우 아래 출력이 발생합니다.
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