首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Python装饰器处理尝试和异常

使用Python装饰器处理尝试和异常
EN

Stack Overflow用户
提问于 2020-05-17 20:57:51
回答 2查看 383关注 0票数 3

如何以装饰器的方式传递try函数和异常处理程序函数

例如,这是WCF连接。

代码语言:javascript
复制
def wcf():
    def send_request(result):
        # establish connection...
        result["response"] = True

    def handle_execption(e, result):
        # logger something
        result["error"] = str(e)
    result = {}
    try:
        send_request(result)
    except Exception as e:
        handle_execption(e, result)

现在,我想在这个连接中添加一个重试机制。实现这个目标的最佳方法是什么,我有多种连接方式(比如RESTSOAP WCF等)?通常,它们共享相同的模式,并且都有send_requesthandle_execption

硬代码之一如下所示,但是在每个协议中添加相同的逻辑是非常愚蠢的。

代码语言:javascript
复制
for attempt in range(0, 3):
    sleep_seconds = attempt ** 2
    sleep(sleep_seconds)

    try:
        send_request(result)
        break
    except Exception as e:
        handle_execption(e, result)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-18 00:55:31

如果您总是以相同的方式处理异常,则可以编写一个装饰器来对该行为进行硬编码并处理重试逻辑:

代码语言:javascript
复制
def retry_decorator(base_function):
    def new_function(*args, **kwargs):  # This allows you to decorate functions without worrying about what arguments they take
        for attempt in range(3):
            sleep_seconds = attempt ** 2
            sleep(sleep_seconds)

            try:
                return base_function(*args, **kwargs)  # base_function is whatever function this decorator is applied to
            except Exception as e:
                print(e)  # Replace this with whatever you want, as long as it's the same for all possible base_functions

    return new_function


@retry_decorator  # Replaces send_request() with retry_decorator(send_request)()
def send_request(result):
    result["response"] = True

如果您想对不同的连接使用不同的异常处理逻辑,事情就会变得更加复杂:

代码语言:javascript
复制
def retry_decorator_2(exception_handle_function):
    def new_decorator(base_function):
        def new_function(*args, **kwargs):
            for attempt in range(3):
                sleep_seconds = attempt ** 2
                sleep(sleep_seconds)

                try:
                    return base_function(*args, **kwargs)
                except Exception as e:
                    exception_handle_function(e)

        return new_function

    return new_decorator


@retry_decorator_2(print)  # Replace 'print' with an exception handling function
def send_request(result):
    result["response"] = True

在本例中,retry_decorator_2(print)创建一个新的装饰器(它将print存储为exception_handle_function),然后将该装饰器应用于send_request函数。

如果需要exception_handle_function接受参数,可以将它们作为装饰器的一部分传递:

代码语言:javascript
复制
def retry_decorator_3(exception_handle_function, *exception_function_args, **exception_function_kwargs):
    def new_decorator(base_function):
        def new_function(*args, **kwargs):
            for attempt in range(3):
                sleep_seconds = attempt
                sleep(sleep_seconds)

                try:
                    return base_function(*args, **kwargs)
                except Exception as e:
                    exception_handle_function(e, *exception_function_args, **exception_function_kwargs)

        return new_function

    return new_decorator


@retry_decorator_3(print, 1, 2, 3)  # 1, 2, 3 become arguments for the print function, or whatever you replace it with
def send_request(result):
    result["response"] = True
票数 2
EN

Stack Overflow用户

发布于 2020-05-17 22:42:06

为什么是装饰师?我觉得它和

代码语言:javascript
复制
def wcf():
    def send_request(result):
        # establish connection...
        result["response"] = True

    def handle_exception(e, result):
        # logger something
        result["error"] = str(e)

    return retry(send_request, handle_exception)


def retry(send_request, handle_exception):
    result = {}

    for attempt in range(0, 3):
        sleep(attempt ** 2)

        try:
            send_request(result)
            return result

        except Exception as e:
            return handle_execption(e, result)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61858705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档