在第三方框架中,源响应函数包含如下:
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')]}
但就我而言,这绝对是一项黑客工作。也许有一些最佳实践来实现这样的更改,甚至更好的方法来修改包装函数的返回而不会失去兼容性?
最后我决定让它变得简单灵活。现在,包装函数应该像往常一样返回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
并重新定义所需的操作之后,它可以工作。