import zmq.green as zmqdef fun(): i = zmq.Context.instance() sock = i.socket(zmq.REQ) sock.connect('tcp://localhost:9005') sock.send('Ping') return sock.recv()
我可以在我的代码中的任何地方运行它作为fun(). .recv()调用在等待回复时阻塞,gevent中心可以调度代码的其他部分.收到值时,函数返回值.
我读了problems that can arise with these implicit returns,我想使用Tornado Ioloop来运行它(也因为我想在IPython Notebook中运行它).以下是一个选项,其中recv_future()返回包含结果的Future:
@gen.coroutinedef fun(): i = zmq.Context.instance() sock = i.socket(zmq.REQ) sock.connect('tcp://localhost:9005') sock.send('Ping') msg = yIEld recv_future(sock) print "Received {}".format(msg[0]) raise gen.Return(msg)def recv_future(socket): zmqstream = ZMQStream(socket) # required for ZMQ future = Future() def _finish(reply): future.set_result(reply) zmqstream.on_recv(_finish) return future
问题是现在fun()不是一个函数,而是一个生成器.因此,如果我需要从另一个函数调用它,我需要使用yIEld fun().但随后调用函数也变成了生成器!
构建使用Python生成器的代码的正确方法是什么?我是否必须使每个功能都成为发电机才能使其工作?如果我需要从__init __()调用其中一个函数怎么办?那还应该成为发电机吗?
解决方法What if I need to call one of these functions from
__init__()
? Should
that also become a generator?
这是目前未解决的问题之一,具有产率/收益率的显式异步编程(在Python 3.3上).魔术方法不支持它们.您可以阅读Python核心开发人员关于异步编程的一些有趣想法,这些想法涉及到这个问题here.
What is the right way to structure code that uses Python generators?
Do I have to make every function a generator to make it work?
Not every function,but every function that you want to call a coroutine,and wait for that coroutine to finish before continuing. When you switch to an explicit asynchronous programming model,you generally want to go all-in with it – your entire program runs insIDe the tornado ioloop. So,with this toy example,you would just do:
from tornado.ioloop import Ioloopfrom tornado.gen import coroutinefrom tornado.concurrent import Future@gen.coroutinedef fun(): i = zmq.Context.instance() sock = i.socket(zmq.REQ) sock.connect('tcp://localhost:9005') sock.send('Ping') msg = yIEld recv_future(sock) print "Received {}".format(msg[0]) raise gen.Return(msg)def recv_future(socket): zmqstream = ZMQStream(socket) # required for ZMQ future = Future() def _finish(reply): future.set_result(reply) zmqstream.on_recv(_finish) return futureif __name__ == "__main__": ioloop = Ioloop.instance() ioloop.add_callback(fun) ioloop.start() # This will run fun,and then block forever. #ioloop.run_sync(fun) # This will start the ioloop,run fun,then stop the ioloop
看起来您可以通过IPython.kernel API访问ioloop IPython正在使用:
In [4]: from IPython.kernel.ioloop import managerIn [5]: manager.ioloop.Ioloop.instance()Out[5]: <zmq.eventloop.ioloop.ZMQIoloop at 0x4249ac8>总结
以上是内存溢出为你收集整理的python – gevent to Tornado ioloop – 结构代码与协同程序/生成器全部内容,希望文章能够帮你解决python – gevent to Tornado ioloop – 结构代码与协同程序/生成器所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)