向包装函数添加第二个返回值,而不会失去向后兼容性

问题描述 投票:3回答:1

在第三方框架中,源响应函数包含如下:

from flask import Response

def wrap_func(func):
    def add_context(*args, **kwargs):
        output_value = func(*args, **kwargs)

        return Response(
            output_value
        )

    return add_context

开发人员可以使用这个装饰器来创建一个类似入口点的自定义函数:

@wrap_function
def hello():
    return '<b>Hello</b>'

框架创建响应并发送它,此功能隐藏在“引擎盖下”。

现在我需要设置一些Response参数,例如我的函数hello中的cookie。如果没有包装器更改似乎是不可能的,我决定为框架做出贡献。

我的第一个是从包装函数(hello)返回一个带有响应参数的可选值,然后在add_context中解析它。注意,向后兼容性很重要,“旧式”功能应该与带有响应参数的“新”功能一样工作。因此,与hello一起,包装器必须支持这样的函数:

@wrap_function
def ping():
    return '<b>Hello</b>', {'cookies': [('te', 'st')]}

但就我而言,这绝对是一项黑客工作。也许有一些最佳实践来实现这样的更改,甚至更好的方法来修改包装函数的返回而不会失去兼容性?

python flask refactoring
1个回答
0
投票

最后我决定让它变得简单灵活。现在,包装函数应该像往常一样返回markdown或Response对象,并使用markdown body初始化。然后,在包装器内部,基于isinstance执行不同的操作。

from flask import Response

def wrap_func(func):
    def add_context(*args, **kwargs):
        output_value = func(*args, **kwargs)

        if isinstance(output_value, Response):
            return output_value
        else:
            return Response(
                output_value
            )

    return add_context

虽然在这个最小的示例包装器之外需要修改响应体,但是在基于CustomResponse创建Response并重新定义所需的操作之后,它可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.