我正在 Tornado 做一个项目这在很大程度上依赖于库的异步特性。通过关注chat demo ,我已经设法让我的应用程序进行长轮询,但是我似乎遇到了所有工作方式的问题。
基本上我想做的是能够调用 UpdateManager
类上的函数并让它完成等待列表中任何回调的异步请求。下面是一些代码来解释我的意思:
更新.py:
class UpdateManager(object):
waiters = []
attrs = []
other_attrs = []
def set_attr(self, attr):
self.attrs.append(attr)
def set_other_attr(self, attr):
self.other_attrs.append(attr)
def add_callback(self, cb):
self.waiters.append(cb)
def send(self):
for cb in self.waiters:
cb(self.attrs, self.other_attrs)
class LongPoll(tornado.web.RequestHandler, UpdateManager):
@tornado.web.asynchronous
def get(self):
self.add_callback(self.finish_request)
def finish_request(self, attrs, other_attrs):
# Render some JSON to give the client, etc...
class SetSomething(tornado.web.RequestHandler):
def post(self):
# Handle the stuff...
self.add_attr(some_attr)
(有更多代码实现 URL 处理程序/服务器等,但我不认为这对于这个问题是必要的)
所以我想做的是让它可以从我的应用程序的另一个地方调用 UpdateManager.send 并且仍然让它将数据发送到等待的客户端。问题是当您尝试这样做时:
from update import UpdateManager
UpdateManager.send()
它只获得 UpdateManager
类,而不是持有用户回调的实例。所以我的问题是:有没有什么方法可以用 Tornado 创建持久对象,让我可以在整个应用程序中共享 UpdateManager
的单个实例?
最佳答案
不要使用实例方法 - 使用 class methods (毕竟,您已经在使用类属性,只是您可能没有意识到)。这样,您不必实例化对象,而是可以调用类本身的方法,它充当单例:
class UpdateManager(object):
waiters = []
attrs = []
other_attrs = []
@classmethod
def set_attr(cls, attr):
cls.attrs.append(attr)
@classmethod
def set_other_attr(cls, attr):
cls.other_attrs.append(attr)
@classmethod
def add_callback(cls, cb):
cls.waiters.append(cb)
@classmethod
def send(cls):
for cb in cls.waiters:
cb(cls.attrs, cls.other_attrs)
这将使...
from update import UpdateManager
UpdateManager.send()
随心所欲地工作。
关于python - 使用 Tornado 拥有持久的运行时对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7379031/