[英]How to call code inside try block one more time if exception is thrown?
我是python的新手,我正在編寫使用OAuth進行身份驗證的代碼,當令牌在60分鍾后過期時,它需要獲得一個新的。
try:
if uploadedContent is not None:
thing.action(uploadedContent)
except LoginOrScopeRequired:
print("Logging in...")
set_access_credentials({"identity", "submit"}, get_access_token())
我目前有這個代碼來處理一個新的令牌,如果它到期,但問題是,如果有一個異常,它跳過它需要做的動作。 我明白我可以把try塊里面的內容添加到except
塊的末尾,但它有更優雅的方法嗎?
我的一些研究,導致了with
聲明,但我不明白with
不夠好,知道這是否能解決我的問題。 那么將它追加到最后的最佳解決方案還是有更好的東西?
使用函數裝飾器/包裝器來執行此操作被認為是慣用的Python:
例:
#!/usr/bin/env python
from functools import wraps
def retry_on_error(ntries=1):
"""
A decorator that returns a wrapper function that calls
the wrapped function repeatedly up to ntries if an
exception is encountered.
"""
def decorator(f): # wrapping the original function
@wraps(f) # make the wrapped function look like the original
def wrapper(*args, **kwargs): # our function wrapped that calls the original
for i in xrange(ntries):
try:
return f(*args, **kwargs)
except Exception as e:
print("Error executing {0:s} retrying {1:d}/{2:d}".format(f.__name__, i, ntries))
print("Error was {0:s}".format(e))
return wrapper
return decorator # returning the new wrapped function
@retry_on_error()
def f():
n = getattr(f, "n", 0)
try:
if not n:
raise ValueError("n < 0")
finally:
setattr(f, "n", n + 1)
輸出:
$ python -i foo.py
>>> f()
Error executing f retrying 0/1
Error was n < 0
>>> f()
>>>
請參閱: Python裝飾器以獲取其他示例。
更新:還有一個很好的庫,它實現了這個功能以及一些其他功能: 重試以及其他一些相關/類似的問題如何在python中的異常后重試? 和Pythonic重試方式運行一個函數
更新#2:我對裝飾器進行了一些評論,所以希望你能夠理解這個過程的每一步都在發生什么。 不可否認,裝飾器起初並不容易理解,因此我建議您閱讀12個簡單步驟中的了解Python裝飾器
像ruby
這樣的某些語言允許你在異常catch塊中放置一個retry
語句,這使得這非常簡單。 不幸的是,在Python中你需要將它包裝在while
語句中:
success = False
while not success
try:
if uploadedContent is not None:
thing.action(uploadedContent)
success = True
except LoginOrScopeRequired:
print("Logging in...")
set_access_credentials({"identity", "submit"}, get_access_token())
請注意,只有在沒有異常發生時才會達到success = True
行success = True
。
編輯
您還需要跟蹤計數器中的attempts
,以確保它不會永遠循環並在3次重試后退出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.