簡體   English   中英

如果拋出異常,如何再次調用try塊中的代碼?

[英]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 = Truesuccess = True

編輯

您還需要跟蹤計數器中的attempts ,以確保它不會永遠循環並在3次重試后退出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM