以下是一些代码:
from flask import Flask, request
import time, threading
class MyServer(Flask):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.reset()
def reset(self):
self.string = "hello"
application = MyServer(__name__)
@application.route("/set")
def set():
application.string = request.args["string"]
threading.Timer(10, application.reset()).start()
return request.args["string"] + " stored for 10 seconds"
@application.route("/get")
def get():
return application.string
if __name__ == "__main__":
application.debug = True
application.run()
我的期望/目标是,如果您访问端点/set?string=foo
,那么在接下来的10秒内,只要您访问/get
,应用就会返回“foo”,之后就会返回“你好,“直到你再次点击/set
端点。
相反,如果我点击/set?string=foo
然后立即'/ get',应用程序返回“hello”,我在控制台中看到“TypeError:'NoneType'对象不可调用”。有人可以帮忙吗?
答案 0 :(得分:4)
以下内容不正确:
threading.Timer(10, application.reset()).start()
Timer的第二个参数需要是一个函数,但实际上你正在调用reset()函数,从而将该方法调用的结果传递给Timer。这就像你做了以下......
result = application.reset()
threading.Timer(10, result).start()
你可能想要做的是以下......
threading.Timer(10, application.reset).start()
话虽这么说,我会非常犹豫是否将此解决方案用于玩具项目以外的任何事情:根据Flask应用程序的部署方式,您实际上可能同时运行多个Flask进程。在这种情况下,此解决方案只会更改您当前正在访问的进程。此外,在每个请求中生成一个新线程可能会导致相当大的开销,具体取决于您的负载。
更好的方法可能是将此数据保存到用户的会话(cookie)或数据库中。您可以使用像Celery或其他消息队列这样的系统来运行异步代码。
如果您需要在一定时间后“过期”数据,还应考虑设置数据过期的日期,然后引入检查过期的代码。因此,您的“set”方法可以同步设置到期时间,“get”端点可以检查过期时间是否已过,并根据该值选择要返回的值。现在您不需要进行异步调用。