def gen():
for i in range(1):
print('i=',i)
X = yield i
print('X=',X)
G = gen()
print('next(G)=',next(G))
print('next(G)=',next(G))
上面代码输出如下,可见如果等号的右边如果是 yield 语句,则等号左边的变量值默认是 None,除非用 send 语句对它赋值:
i= 0
next(G)= 0
X= None
Traceback (most recent call last):
File "c:\Users\rubin\AppData\Roaming\Code\User\rb\t.py", line 9, in
print('next(G)=',next(G))
StopIteration
但是对于下面的例子来说,即使没有用 send 语句,yield 返回的值也能赋值给等号左边的变量 reader 和 writer。
import asyncio
@asyncio.coroutine
def wget(host):
print('wget %s...' % host)
connect = asyncio.open_connection(host, 80)
reader, writer = yield from connect #yield 返回的值也能赋值给等号左边的变量
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
print('reader=%s write=%s' % (reader,writer))
writer.write(header.encode('utf-8'))
yield from writer.drain()
writer.close()
loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sohu.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
上面代码输出如下:
wget www.sohu.com. ..
reader=<StreamReader t=<_SelectorSocketTransport fd=592 read=polling write=<idle, bufsize=0>>> write=<StreamWriter transport=<_SelectorSocketTransport fd=592 read=polling write=<idle, bufsize=0>> reader=<StreamReader t=<_SelectorSocketTransport fd=592 read=polling write=<idle, bufsize=0>>>>
为何等号左边的变量 reader 和 writer 不是 None ?请问这是什么原理呢?谢谢!
1
smallzhan 2017-11-08 21:15:33 +08:00
一个是 yield,一个是 yield from。
yield 和 yield from 是不同的,你可以看看 fluent python,coroutine 那章讲这个的。顺便还有 asyncio 那章。 |
2
xlui 2017-11-08 22:27:38 +08:00 via Android
第二个例子中的 connect 变量是一个 generator,yield from 会自动对它进行预激,也就是调用 next(connect),并且自动迭代 connect 生成值,然后返回结果。具体可以去看 流畅的 Python,这本书真的值得买回来。
|
3
guyskk0x0 2017-11-08 22:50:55 +08:00 via Android
@asyncio.coroutine 会自动帮你调用 send,过程比较 复杂,可以到 YouTube 上搜 async 或 coroutine,有很多大牛的演讲视频。
|
4
wzwwzw 2017-11-09 15:38:32 +08:00
看下流畅的 Python 16 章节 。
|