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
xing393939
V2EX  ›  Python

yield 和 return 混用的问题

  •  
  •   xing393939 ·
    xing393939 · 224 天前 · 2822 次点击
    这是一个创建于 224 天前的主题,其中的信息可能已经有所发展或是发生改变。
    def fun1(batch):
        if batch:
            return range(10)
        else:
            for item in range(10):
                yield item
    
    
    a = fun1(True)
    for v in list(a):
        print(v)
    print("-------------")
    b = fun1(False)
    for v in list(b):
        print(v)
    

    直觉上最后的结果分割线之上也是能输出 0~9 的,但是实际上是空,把 yield 改成 return 就好了,这是什么原因呢?

    12 条回复    2024-04-22 12:31:35 +08:00
    leonshaw
        1
    leonshaw  
       224 天前
    In a generator function, the return statement indicates that the generator is done and will cause StopIteration to be raised. The returned value (if any) is used as an argument to construct StopIteration and becomes the StopIteration.value attribute.
    jadehare
        2
    jadehare  
       224 天前
    @leonshaw https://v2ex.com/about 看看规则最后一条
    SantuZ
        3
    SantuZ  
       224 天前
    GPT 回答:
    在 Python 中,return 和 yield 可以出现在同一个函数中,但它们的作用和影响是截然不同的:

    return 在函数中用来返回一个值,并结束函数的执行。一旦函数执行到 return 语句,函数会立即结束,并且只能返回一次值。
    yield 使函数成为一个生成器函数。使用 yield 的函数每执行到一个 yield 语句,就会产生一个值,并在那个点暂停执行,等待下一次迭代请求值。
    当 yield 和 return 在同一个函数中共存时,需要注意以下几点:

    如果函数中包含 yield 语句,该函数就是一个生成器函数,调用该函数将返回一个生成器对象,而不是直接执行函数中的代码。

    在生成器函数中使用 return 语句可以用来提供生成器的终止原因,但这不会返回值给调用者。在 Python 3.3 及以上版本中,当生成器正常完成迭代时,任何 return 语句中的返回值都会被包装进一个 StopIteration 异常中。通过 StopIteration 异常的.value 属性可以访问到 return 语句中的返回值。

    如果 return 语句后有返回值,该值会成为生成器终止时 StopIteration 异常的属性。如果 return 没有返回值(即 return 或 return None ),生成器终止时不会有 StopIteration 值。

    一旦执行到 return 语句,即使是在生成器函数中,函数也会立即结束。后续的 yield 语句将不会执行。

    def my_generator():
    yield 1
    return "No more elements" # 结束生成器,并指示原因
    yield 2 # 这行代码不会被执行

    gen = my_generator()

    try:
    print(next(gen)) # 输出 1
    print(next(gen)) # 触发 StopIteration 异常
    except StopIteration as e:
    print(e.value) # 输出 "No more elements"
    leonshaw
        4
    leonshaw  
       224 天前
    @jadehare 啥意思
    lovelylain
        5
    lovelylain  
       224 天前
    一个函数中出现 yield 语句后,就不再是函数而是生成器了,生成器中 return x 等价于 raise StopIteration(x),大部分时候它只是使迭代停止的特殊异常,不关心这个返回值。如果你需要 True 分支能输出 0~9 ,可以把 return range(10)改为 yield from range(10)
    NoOneNoBody
        6
    NoOneNoBody  
       224 天前
    @jadehare #2
    @leonshaw #1 的回复不是 AI 生成的,就是从手册复制的说明,我刚刚还想粘贴过来呢,看到#1 已经做了,就不需要了
    zzl22100048
        7
    zzl22100048  
       224 天前
    不能 return 可以 yield from
    jadehare
        8
    jadehare  
       224 天前
    @leonshaw #4 以为是 ai 生成的回答,不是的话不好意思。
    noahlias
        9
    noahlias  
       224 天前
    If the compiler detects the yield keyword anywhere inside a function, that function no longer returns via the return statement. Instead, it immediately returns a lazy "pending list" object called a generator


    https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python
    krixaar
        10
    krixaar  
       224 天前
    @jadehare #2
    在一个生成器函数中,return 语句表示生成器已完成并将导致 StopIteration 被引发。 返回值(如果有的话)会被当作一个参数用来构建 StopIteration 并成为 StopIteration.value 属性。

    https://docs.python.org/zh-cn/3/reference/simple_stmts.html#the-return-statement

    Python 官方文档里的,不是 AI 生成的,多虑了😂
    leonshaw
        11
    leonshaw  
       224 天前
    @jadehare 嗯,是文档里的
    oDVN6afUQ2v29715
        12
    oDVN6afUQ2v29715  
       213 天前
    生成器本质上也就是一个迭代器,他里面的一个关键点就是`yield`关键字,当 Python 执行到 yield 语句时,它会生成一个值,然后暂停函数的执行。当下一次调用生成器的`next()`函数时,它会从上次暂停的地方继续执行,直到再次遇到`yield`语句。

    `yield`和`return`的区别是:`yield`可以有多个,`return`只能有一个,但站在功能的角度:都是返回值。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1467 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:13 · PVG 01:13 · LAX 09:13 · JFK 12:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.