推荐学习书目
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 · Apr 11, 2024 · 4812 views
    This topic created in 805 days ago, the information mentioned may be changed or developed.
    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 replies    2024-04-22 12:31:35 +08:00
    leonshaw
        1
    leonshaw  
       Apr 11, 2024
    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  
       Apr 11, 2024
    @leonshaw https://v2ex.com/about 看看规则最后一条
    SantuZ
        3
    SantuZ  
       Apr 11, 2024
    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  
       Apr 11, 2024
    @jadehare 啥意思
    lovelylain
        5
    lovelylain  
       Apr 11, 2024
    一个函数中出现 yield 语句后,就不再是函数而是生成器了,生成器中 return x 等价于 raise StopIteration(x),大部分时候它只是使迭代停止的特殊异常,不关心这个返回值。如果你需要 True 分支能输出 0~9 ,可以把 return range(10)改为 yield from range(10)
    NoOneNoBody
        6
    NoOneNoBody  
       Apr 11, 2024
    @jadehare #2
    @leonshaw #1 的回复不是 AI 生成的,就是从手册复制的说明,我刚刚还想粘贴过来呢,看到#1 已经做了,就不需要了
    zzl22100048
        7
    zzl22100048  
       Apr 11, 2024
    不能 return 可以 yield from
    jadehare
        8
    jadehare  
       Apr 11, 2024
    @leonshaw #4 以为是 ai 生成的回答,不是的话不好意思。
    noahlias
        9
    noahlias  
       Apr 11, 2024
    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  
       Apr 11, 2024
    @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  
       Apr 11, 2024
    @jadehare 嗯,是文档里的
    oDVN6afUQ2v29715
        12
    oDVN6afUQ2v29715  
       Apr 22, 2024
    生成器本质上也就是一个迭代器,他里面的一个关键点就是`yield`关键字,当 Python 执行到 yield 语句时,它会生成一个值,然后暂停函数的执行。当下一次调用生成器的`next()`函数时,它会从上次暂停的地方继续执行,直到再次遇到`yield`语句。

    `yield`和`return`的区别是:`yield`可以有多个,`return`只能有一个,但站在功能的角度:都是返回值。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3229 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 11:52 · PVG 19:52 · LAX 04:52 · JFK 07:52
    ♥ Do have faith in what you're doing.