V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
saximi
V2EX  ›  Python

关于 yield 返回值的问题请教

  •  
  •   saximi · 2017-11-08 18:57:06 +08:00 · 3590 次点击
    这是一个创建于 2606 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 ?请问这是什么原理呢?谢谢!

    4 条回复    2017-11-09 15:38:32 +08:00
    smallzhan
        1
    smallzhan  
       2017-11-08 21:15:33 +08:00
    一个是 yield,一个是 yield from。
    yield 和 yield from 是不同的,你可以看看 fluent python,coroutine 那章讲这个的。顺便还有 asyncio 那章。
    xlui
        2
    xlui  
       2017-11-08 22:27:38 +08:00 via Android
    第二个例子中的 connect 变量是一个 generator,yield from 会自动对它进行预激,也就是调用 next(connect),并且自动迭代 connect 生成值,然后返回结果。具体可以去看 流畅的 Python,这本书真的值得买回来。
    guyskk0x0
        3
    guyskk0x0  
       2017-11-08 22:50:55 +08:00 via Android
    @asyncio.coroutine 会自动帮你调用 send,过程比较 复杂,可以到 YouTube 上搜 async 或 coroutine,有很多大牛的演讲视频。
    wzwwzw
        4
    wzwwzw  
       2017-11-09 15:38:32 +08:00
    看下流畅的 Python 16 章节 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2746 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:12 · PVG 21:12 · LAX 05:12 · JFK 08:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.