简体   繁体   English

如果抛出异常,如何再次调用try块中的代码?

[英]How to call code inside try block one more time if exception is thrown?

I am new to python and I am writing code that uses OAuth to authenticate and when the token expires after 60 minutes, it needs to get a new one. 我是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())

I currently have this code to handle getting a new token if it expires, but the problem is that if there was an exception it skips over the action it needed to do. 我目前有这个代码来处理一个新的令牌,如果它到期,但问题是,如果有一个异常,它跳过它需要做的动作。 I understand that I could take what was inside the try block and append it to end of the except block, but it there a more elegant way to do this? 我明白我可以把try块里面的内容添加到except块的末尾,但它有更优雅的方法吗?

Some of my research led to the with statement, but I didn't understand with well enough to know if it would solve my problem. 我的一些研究,导致了with声明,但我不明白with不够好,知道这是否能解决我的问题。 So is appending it to the end the best solution or is there something better? 那么将它追加到最后的最佳解决方案还是有更好的东西?

It is considered Idiomatic Python to do this with a function decorator/wrapper: 使用函数装饰器/包装器来执行此操作被认为是惯用的Python:

Example: 例:

#!/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)

Output: 输出:

$ python -i foo.py
>>> f()
Error executing f retrying 0/1
Error was n < 0
>>> f()
>>> 

See: Python Decorators for other examples. 请参阅: Python装饰器以获取其他示例。

Update: There is also a nice library that implements this functionality with a few more features: retrying as well as several other related/similar questions How to retry after exception in python? 更新:还有一个很好的库,它实现了这个功能以及一些其他功能: 重试以及其他一些相关/类似的问题如何在python中的异常后重试? and Pythonic way of retry running a function Pythonic重试方式运行一个函数

Update #2: I've commented the decorator a bit so hopefully you can understand what's going on in each step of the process. 更新#2:我对装饰器进行了一些评论,所以希望你能够理解这个过程的每一步都在发生什么。 Admittedly decorators aren't that easy to understand at first so I recommend you read Understanding Python Decorators in 12 easy step 不可否认,装饰器起初并不容易理解,因此我建议您阅读12个简单步骤中的了解Python装饰器

Some languages like ruby let you put a retry statement in the exception catch block that makes this incredibly simple. ruby这样的某些语言允许你在异常catch块中放置一个retry语句,这使得这非常简单。 Unfortunately in Python you will need to wrap this in a while statement: 不幸的是,在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())

Note that the line success = True will only be reached if no exception occurs. 请注意,只有在没有异常发生时才会达到success = Truesuccess = True

EDIT 编辑

You will also want to keep track of the number of attempts in a counter to ensure this doesn't loop forever and exits after 3 retries for example. 您还需要跟踪计数器中的attempts ,以确保它不会永远循环并在3次重试后退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用try异常块同时运行两个功能 - How to run two function in the same time with using try exception block Selenium NoSuchElement 异常仍在尝试块中抛出 - Selenium NoSuchElement exception is still being thrown in a try block 在try块中打印时发生异常 - Exception while printing inside a try block 如果 try 块的某个方面失败,则继续运行代码,但仍会引发异常 - Continue running code if one aspect of a try block fails, but still raise the exception 在python中,是否可能在调用之后但紧随其后的try块之前发生异常? - in python, is it possible for an exception to occur after a call but “before” the try block that follows it? 如何使用try Exception块保存代码以防止异常终止? - How to use try Exception block to save my code from abnormal termination? 捕获由try-block内的函数引发的自定义异常 - Catch custom Exception that is raised by a function inside the try-block 如何调试 try except 块内的异常? - How to debug on exceptions inside try except block? 如何将try和except合并到python中的代码块中 - how to incorporate try and except into a block of code in python 如何使用 try/except 块优化代码? - How to optimize the code with try/except block?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM