kivy中超过最大递归深度,但仅在打包时,而不是在python中开发应用程序时

5cg8jx4n  于 2024-01-05  发布在  Python
关注(0)|答案(3)|浏览(178)

我正在尝试打包一个需要几个导入的应用程序,其中包括matplotlib.pyplot
kivy应用程序(简化,但仍然工作)是:

  1. from kivy.app import App
  2. from kivy.uix.boxlayout import BoxLayout
  3. from kivy.lang import Builder
  4. import matplotlib.pyplot
  5. Builder.load_string("""
  6. <MyWidget>:
  7. id: my_widget
  8. FileChooserIconView:
  9. id: filechooser
  10. on_selection: my_widget.selected(filechooser.selection)
  11. Image:
  12. id: image
  13. source: ""
  14. """)
  15. class MyWidget(BoxLayout):
  16. def selected(self,filename):
  17. self.ids.image.source = filename[0]
  18. class MyApp(App):
  19. def build(self):
  20. return MyWidget()
  21. if __name__ == '__main__':
  22. MyApp().run()

字符串
这个应用程序在使用spyder的python中工作得很完美。
然而,当我试图将其打包为一个独立的kivy应用程序时,它给了我超过最大递归深度的错误。
我很惊讶,也不知道问题出在哪里,因为:
1.该应用程序中没有递归函数。
2.完美的作品在python spyder,而开发和测试它,唯一的问题是在 Package 。
3.我尝试了多种方法,包括注解掉几个部分,最令人惊讶的是,当我注解掉导入matplotlib.pyplot时,应用程序包很好。但是,我需要matplotlib.pyplot来运行这个应用程序,所以不可以将其删除。

  1. from kivy.app import App
  2. from kivy.uix.boxlayout import BoxLayout
  3. from kivy.lang import Builder
  4. #import matplotlib.pyplot
  5. Builder.load_string("""
  6. <MyWidget>:
  7. id: my_widget
  8. FileChooserIconView:
  9. id: filechooser
  10. on_selection: my_widget.selected(filechooser.selection)
  11. Image:
  12. id: image
  13. source: ""
  14. """)
  15. class MyWidget(BoxLayout):
  16. def selected(self,filename):
  17. self.ids.image.source = filename[0]
  18. class MyApp(App):
  19. def build(self):
  20. return MyWidget()
  21. if __name__ == '__main__':
  22. MyApp().run()


上面的代码运行良好,并且打包得很好。
是不是有一些文件的大小限制,一个人可以导入到一个kivy应用程序?我已经尝试过增加递归限制与sys.setrecursionlimit(高数字),但它不是一个解决这个问题的办法。我真的迷失了。任何见解赞赏。
谢谢你
编辑2/4/2019:有人认为问题:pyinstaller creating EXE RuntimeError: maximum recursion depth exceeded while calling a Python object是一个重复的问题,并且回答了这个问题。虽然这是一个明确的相关问题,并且很有帮助,但我的错误发生在创建kivy包的第一个阶段:python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py

cuxqih21

cuxqih211#

非常感谢大家谁试图帮助.我找到了一个答案,我希望它能帮助其他人谁试图创建一个kivy包,有一个问题导入python模块(s).
一旦你准备好打包你的main.py脚本:
1.从以下说明开始:

  1. https://kivy.org/doc/stable/guide/packaging-windows.html

字符串
做第一步:

  1. python -m PyInstaller --name touchtracer examples-path\demo\touchtracer\main.py


这将给予你的错误maximum recursion depth exceeded或任何错误这给你原来。不用担心。这一步的目的是创建一个初始spec文件。
2.打开spec文件,并添加kivy说明给予的所有额外内容,

  1. https://kivy.org/doc/stable/guide/packaging-windows.html


即:

  1. from kivy.deps import sdl2, glew
  2. Tree('examples-path\\demo\\touchtracer\\'),
  3. *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],


3.除此之外,在spec文件的开头添加以下内容:

  1. import sys
  2. sys.setrecursionlimit(5000) # (or some big number)


4.还可以在隐藏导入中添加您可能需要的任何导入。

  1. hiddenimports=[] # change to (example importing pandas and matplotlib) hiddenimports=['pandas', 'matplotlib']


5.只要按照最后一步,

  1. https://kivy.org/doc/stable/guide/packaging-windows.html


即:

  1. python -m PyInstaller touchtracer.spec


并构建您的应用程序

展开查看全部
ldioqlga

ldioqlga2#

当我们进入递归时,有一个堆栈溢出的风险,并且Cpython不会自己优化尾部递归,所以如果你进入得太深,你会更接近堆栈溢出。通常,不同的Cpython/python风格有不同的递归允许深度,您在本地运行的python版本具有更自由的深度限制(通常是因为假设开发人员有足够好的计算机,可以进行此操作)。但是,当您使用工具打包应用程序时,它们通常会将sys.setrecursionlimit重写为更保守的值,因为它们会尝试确保您不会在具有降低硬件成本。
遗憾的是,没有解决这个问题的银,您可以尝试查看您的特定管理器并更改限制(不推荐),或者尝试将递归块转换为迭代块。

p8ekf7hl

p8ekf7hl3#

此问题是由PyInstaller 5.6以上版本引起的,该版本在窗口模式下不再创建假sys.stdout/sys.stderr。相反,两者都保留为None,这与pythonw.exe的操作相匹配。如果kivy.logger盲目地写入sys.stderr而没有首先检查它是否存在,那么这就是kivy的错误。我希望Kivy将包括标准输出/logger.py中的错误检查很快将与PyInstaller 5.7.0+兼容
现在你可以通过显式设置环境或启用控制台构建或降级PyInstaller来手动绕过这个bug。
下面提到的片段应在导入kivy之前添加。

  1. import os,sys
  2. if sys.__stdout__ is None or sys.__stderr__ is None:
  3. os.environ['KIVY_NO_CONSOLELOG'] = '1'

字符串

相关问题