El martes, 28 de julio de 2015, 23:18:11 (UTC+2), Javier escribió: > El martes, 21 de julio de 2015, 15:42:47 (UTC+2), Ian escribió: > > On Tue, Jul 21, 2015 at 5:31 AM, <jcarm...@gmail.com> wrote: > > > Hello, I'm trying to understand and link asyncio with ordinary > > > coroutines. Now I just want to understand how to do this on asyncio: > > > > > > > > > def foo(): > > > data = yield 8 > > > print(data) > > > yield "bye" > > > > > > def bar(): > > > f = foo() > > > n = f.next() > > > print(n) > > > message = f.send("hello") > > > print(message) > > > > > > > > > What is the equivalent for coro.send("some data") in asyncio? > > > > I don't know of any reason why you couldn't do it just like the above. > > However, the exchange would not be asynchronous, if that is your goal. > > > > > coro.send on an asyncio coroutine throws AssertionError: yield from > > > wasn't used with future. > > > > So somehow a future got involved where it shouldn't have been. What > > was the actual code that you tried to run? > > > > Note that while "yield" and "yield from" look similar, they are quite > > different, and you cannot send to a generator that is currently paused > > at a "yield from". > > > > If you want to emulate bidirectional communication similar to > > coro.send asynchronously, I think you'll need to use Futures to > > mediate, something like this (lightly tested): > > > > @asyncio.coroutine > > def foo(fut): > > data, fut = yield from send_to_future(8, fut) > > print("foo", data) > > fut.set_result("bye") > > > > @asyncio.coroutine > > def bar(): > > n, fut = yield from start_coro(foo) > > print("bar", n) > > message = yield from send_to_future("hello", fut) > > print("bar", message) > > > > def start_coro(coro): > > future = asyncio.Future() > > asyncio.async(coro(future)) > > return future > > > > def send_to_future(data, future): > > new_future = asyncio.Future() > > future.set_result((data, new_future)) > > return new_future > > > > > Hello again. I have been investigating a bit your example. I don't understand > why I can't write something like this: > > -------- > > import asyncio > > def foo(): > print("start foo") > try: > while True: > val = yield > print("foo:", val) > yield from asyncio.sleep(3) > except GeneratorExit: > print("foo closed") > print("exit foo") > > def bar(next): > print("start bar") > next.send(None) > try: > while True: > val = yield > next.send("bar/"+val) > except GeneratorExit: > print("bar closed") > print("exit bar") > > def fun(next): > next.send(None) > for e in ["hello", "world", "I'm", "pythonist"]: > next.send(e) > > @asyncio.coroutine > def run(): > fun(bar(foo())) > > loop = asyncio.get_event_loop() > loop.run_until_complete(run()) > loop.close() > > ------- > > The expected output is: > > start bar > start foo > foo: bar/hello > foo: bar/world > foo: bar/I'm > foo: bar/phytonist > bar closed > exit bar > foo closed > exit foo > > But the yield from asyncio.sleep(3) call raises AssertionError, however it's > inside a Task! > I think this is a big flaw in python/asyncio design.
I think that force the developer to 'yield from' all function calls to keep async capabilities is a big mistake, it should be more flexible, like this: import asyncio @asyncio.coroutine fun non_blocking_io(): """ Everybody knows I'm doing non blocking IO """ ... fun foo(): """ I invoke functions that do IO stuff """ data = yield from non_blocking_io() yield from store_data_db(data) ... fun bar(): """ I don't know what foo implementation does """ foo() asyncio.async(bar()) Does python 3.5 await/async solve this? -- https://mail.python.org/mailman/listinfo/python-list