Flask 资源是什么时候创建的?

zmb*_*mbq 5 python flask

我是烧瓶的新手。我有一个处理 POST 请求的资源类。请求处理相当精细,不能全部在post函数中。我是否为每个请求获得一个新的 Resource 实例?或者实例被重用?我这样做是否安全:

class MyResource(Resource):
    def post(self):
        self.var = 17
        self.do_some_work()
        return self.var * self.var
Run Code Online (Sandbox Code Playgroud)

Flask 是否保证我的资源实例不会用于其他事务?

小智 3

资源对象是在请求得到服务时创建的,并且它们不是持久的。请记住,REST 原则规定 API 必须是无状态的。如果你想在请求之间存储数据,你应该使用某种数据库。

证明我所说的最简单的方法是在您的 get 处理程序中使用 aprint (id(self))并触发几次请求。你会发现对象总是在变化。

现在,如果您对Flask 内部结构感兴趣,我们就开始吧。Resource类是Flask-RESTtful的一部分,文档说明如下:

资源构建在 Flask 可插入视图之上,让您只需在资源上定义方法即可轻松访问多个 HTTP 方法。

资源是通过Resource.add_resource()方法添加的,它只是简单地注册底层View对象。

if self.app is not None:
    self._register_view(self.app, resource, *urls, **kwargs)
else:
    self.resources.append((resource, urls, kwargs))
Run Code Online (Sandbox Code Playgroud)

Resource._register_view()方法做了很多疯狂的事情,但最有意义的是这两行:

resource_func = self.output(resource.as_view(endpoint, *resource_class_args, **resource_class_kwargs))
...
self.blueprint_setup.add_url_rule(url, view_func=resource_func, **kwargs)
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到视图对象提供了一个与 URL 路径关联的处理程序。每次对此路由发出 HTTP 请求时都会调用此处理程序。

最后,我们到达了核心,在View.as_view()方法中,它动态创建一个函数,该函数将代表路由处理程序。

def view(*args, **kwargs):
    self = view.view_class(*class_args, **class_kwargs)
    return self.dispatch_request(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,每次必须分派请求时,此函数都会创建一个新对象,并且正如您已经猜到的那样,该函数view_class包含用于处理请求的自定义类。