"运行时错误:生成器引发了StopIteration" 每次我尝试运行应用程序时。

81

我正试图在Python 3.7中运行这段代码:

import web

urls = ('/', 'index')

if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

每次都给我这个错误:
C:\Users\aidke\Desktop>python app.py
Traceback (most recent call last):
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\utils.py", line 526, in take
    yield next(seq)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "app.py", line 14, in <module>
    app = web.application(urls, globals())
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\application.py", line 62, in __init__
    self.init_mapping(mapping)
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\application.py", line 130, in init_mapping
    self.mapping = list(utils.group(mapping, 2))
  File "C:\Users\aidke\AppData\Local\Programs\Python\Python37-32\lib\site-packages\web\utils.py", line 531, in group
    x = list(take(seq, size))
RuntimeError: generator raised StopIteration

我尝试了别人的代码,结果出现了完全相同的问题。此外,我还尝试重新安装web.py(实验版),但仍然无法解决问题。

Python 3.7 的循环现在更加困难,需要更深入地了解 Python(生成器)的内部机制。而 Java 的 for-each 循环现在比 Python 更容易。 - barrypicker
7个回答

138
根据文件路径,看起来你正在运行Python 3.7。如果是这样,你就会被Python 3.7的新特性所困扰:PEP 479 已启用,意味着协程和生成器中直接或间接引发的StopIteration异常会转换为RuntimeError异常。(由Yury Selivanov在bpo-32670中贡献。) 在此更改之前,由生成器引发或通过生成器传递的StopIteration异常只会结束生成器的有用生命(该异常会被静默吞噬)。你正在使用的模块将需要重新编码以在Python 3.7中正常工作。很可能他们需要改变:
yield next(seq)

致:

try:
    yield next(seq)
except StopIteration:
    return

2
那么,如果这是在第三方应用程序中,您需要升级它吗?如果该第三方应用程序未针对PEP 479进行修复,那么您是否无法解决问题? - Scott Skiles
4
当然,除非他们改变了应用程序,否则升级应用程序不会有任何区别。如果他们没有改变应用程序,您可以自己修补它。或者在重要的应用程序兼容PEP 479之前,不要将其迁移到Python 3.7。由于我很少看到这个问题在实际使用中出现,所以我认为这是一个罕见的问题。 - Tim Peters
2
@CozyAzure,请阅读PEP,这是你可以获得的唯一更改理由。在此更改之前,“StopIteration”在生成器中被静默吞噬,正如原始生成器 PEP(255)所规定的那样。因此,建议的代码只是恢复了多年来生成器的行为。 - Tim Peters
1
另一个很好的解决方案,根据上下文而定,是将默认值传递给next,而不是使用try-except块:yield next(seq, None) - bryant1410
1
但请注意@bryant1410的“根据上下文而定”。yield next(seq, None)的行为因上下文不同而有很大区别:它并不会结束包含生成器的生命周期,而是产生一个额外的Nene值,这个值seq本身没有提供。根据上下文来看,这可能是无害的,也可能是灾难性的。给出的答案无论上下文如何都复制了3.6版本的行为。 - Tim Peters
显示剩余6条评论

3

我的解决方案是将以下 pip 包进行升级:

mongoengine0.14.0 升级到 0.19.1

flask-mongoengine 升级到 0.9.5

这样做起作用了。


我如何为鸡蛋做到这一点? - mLstudent33

3

最近在自学Python时,有门课程要求我安装Web.py,但我遇到了错误,其中一个回答说需要更新以与Python 3.7兼容。

我用pip3 install web.py==0.40-dev1安装了该软件包,然后遇到了这个错误,开始在网上寻找解决方案。

我的做法是搜索webpy git,找到https://github.com/webpy/webpy/tree/master/web中更新的utils.py文件,下载它,并用它替换我Lib/site-packages/web文件夹中的那个文件(我是Windows用户),这样就可以成功了。

希望能对某些人有所帮助。


2

现在大多数主要软件包已经修复了这个问题,但是一个尚未修复的主要软件包是clips/pattern项目。该项目自2018年8月以来没有更新过,因此从未获得修复。

由于这是“python pattern stopiteration”的顶级Google搜索结果,因此这里提供一个解决方法:

def pattern_stopiteration_workaround():
    try:
        print(lexeme('gave'))
    except:
        pass

def main():
    pattern_stopiteration_workaround()
    #Add your other code here

基本上,与模式相关的代码只会在第一次运行时失败,因此您需要先运行它一次并捕获它抛出的异常。
对于我的脚本来说,这个方法已经足够好用,但我不确定它是否可以解决所有可能的问题。
理想情况下,应该有人分叉 clips/pattern 项目,因为它已经不再维护。

1
他们已经解决了这个问题,只需卸载您当前的web.py版本,当我在windows 10上运行pip install web.py时出现错误。所以我运行pip install -e git+https://github.com/webpy/webpy.git#egg=webpy命令从master分支获取最新版本。这样就不会像问题中提到的那样出现RuntimeError: generator raised StopIteration错误。

我收到了一个警告,但这并没有解决它。 - mLstudent33
WARNING: Generating metadata for package webpy produced metadata for project name web-py. Fix your #egg=webpy fragments. - mLstudent33

0

-2

我遇到了与下面命令相同的问题

python setup.py test

当我升级pytest版本后,错误问题得到了解决。

pip uninstall pytest
pip install pytest

如果你不知道,**pip install -U pytest** 会导致 pip 进行升级;没有 -U 选项,它只会说该软件包已经安装。 - Alastair Irvine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接