当我编译python代码时,我得到:RecursionError:调用Python对象时超出了最大递归深度 [英] When i compile my python code i get: RecursionError: maximum recursion depth exceeded while calling a Python object

查看:100
本文介绍了当我编译python代码时,我得到:RecursionError:调用Python对象时超出了最大递归深度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

edit:使用cython编译的pyqt5尝试了等效的代码.它可以顺畅地工作,所以这似乎是pyside2错误.

edit: Tried the equivalent code with pyqt5 compiled with cython. It works swimmingly so this seems to be a pyside2 bug.

最新版本的cython.当我使用python运行它时,我的应用程序运行良好,但是当我将其制作成模块并从简单的启动器脚本导入该模块时,它似乎看不到来自互联网的任何数据,并且还为我提供了这些信息:RecursionError:maximum调用Python对象时超出了递归深度.

Latest version of cython. My app works fine when i run it with python but when i make it into a module and import the module from a simple launcher script suddenly it doesn't seem to see any data from the internet and it also gives me these: RecursionError: maximum recursion depth exceeded while calling a Python object.

Nuitka有相同的问题,但没有给我这些递归错误.

Nuitka has the same problem but doesn't give me these recursionerrors.

我不知道它是否相关,但是在用gcc编译程序(制作目标代码)时,我也得到了这个错误/警告/注意(唯一的一个):

I have no idea if it's relevant but when compiling the program(making object code) with gcc i also get this error/warning/note(the only one):

$ python setup.py build_ext --inplace
Compiling prog.py because it changed.
[1/1] Cythonizing prog.py
running build_ext
building 'prog' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 
-Wall -Wstrict-prototypes -march=x86-64 -mtune=generic -O2 -pipe -
fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -O2 -
pipe -fstack-protector-strong -fno-plt -march=x86-64 -mtune=generic -
O2 -pipe -fstack-protector-strong -fno-plt -fPIC -
I/usr/include/python3.6m -c prog.c -o build/temp.linux-x86_64-
3.6/prog.o
prog.c: In function ‘__pyx_pf_4prog_13Ui_MainWindow_setupUi.isra.76’:
prog.c:41235:18: note: variable tracking size limit exceeded with -
fvar-tracking-assignments, retrying without
static PyObject *__pyx_pf_4prog_13Ui_MainWindow_setupUi(CYTHON_UNUSED 
PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_MainWindow) {
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

也不确定是否相关,但是我有一堆类(线程),当一个循环结束时,它们会调用下一个类.即使在python中也可以正常工作,这也许是一个nono吗?

Also not sure if relevant but i have a bunch of classes(threads) that calls the next class when one is finished making a loop. Maybe this is a nono even if it works fine in python?

我正在使用pyside2,request,delorean和humanize.我什至不知道如何开始调试它,它是一个4000行的程序.

I'm using pyside2, requests, delorean and humanize. Im not even sure how to start debugging this, it's a 4000 line program.

好的,所以我设法在一个最小的例子中重现了确切的问题.在使用cython或nuitka进行编译之前,此代码将完美运行.如果您使用cython进行编译,则会输出:

edit: Ok so i managed to reproduce the exact problem in a minimal example. This code will work perfectly before you compile it with cython or nuitka. If you compile it with cython it will output:

('thread1:', <Response [200]>)
RecursionError: maximum recursion depth exceeded while calling a Python object

并挂起,但它将显示窗口内容.使用nuitka,它将永远不会显示窗口的内容,但是线程将按预期运行.如果有人能解释它发生的原因以及我如何解决它,那将是很好的:

and hang but it will show the window contents. With nuitka it will never show the contents of the window but the threads will run as expected. If anyone can explain why it happens and how i can fix it that would be great:

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Slot, Signal, QThread
import sys
import requests

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(240, 100, 97, 34))
        self.pushButton.setObjectName("pushButton")
        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit.setGeometry(QtCore.QRect(200, 160, 451, 271))
        self.plainTextEdit.setPlainText("")
        self.plainTextEdit.setObjectName("plainTextEdit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "OK"))

class MainUIClass(QtWidgets.QMainWindow, Ui_MainWindow):
    def closeEvent(self, evnt):
        print("CLOSED")
        self.thread1.quit()
        self.thread2.quit()
        self.thread3.quit()
        self.thread1.wait()
        self.thread2.wait()
        self.thread3.wait()
        print("thread1 is running?:", self.thread1.isRunning())
        print("thread2 is running?:", self.thread2.isRunning())
        print("thread3 is running?:", self.thread3.isRunning())
        sys.exit()

    def __init__(self, parent=None):
        super().__init__()
        self.setupUi(self)

        self.thread1 = QThread()
        self.thread2 = QThread()
        self.thread3 = QThread()

        self.Class1 = Class1()
        self.Class2 = Class2()
        self.Class3 = Class3()

        self.Class1.moveToThread(self.thread1)
        self.Class2.moveToThread(self.thread2)
        self.Class3.moveToThread(self.thread3)

        self.thread1.started.connect(lambda: self.Class1.startThread())

        self.Class1.startThread2.connect(self.Class2.startThread)
        self.Class2.startThread3.connect(self.Class3.startThread)
        self.Class3.startThread1.connect(self.Class1.startThread)

        self.thread1.start()
        self.thread2.start()
        self.thread3.start()

class Class1(QtCore.QObject):
    startThread2 = Signal()

    def __init__(self):
        super().__init__()

    def startThread(self):
        data = requests.get("https://www.google.com")
        print("thread1:", data)
        self.startThread2.emit()

class Class2(QtCore.QObject):
    startThread3 = Signal()

    def __init__(self):
        super().__init__()

    def startThread(self):
        data = requests.get("https://www.google.com")
        print("thread2:", data)
        self.startThread3.emit()

class Class3(QtCore.QObject):
    startThread1 = Signal()

    def __init__(self):
        super().__init__()

    def startThread(self):
        data = requests.get("https://www.google.com")
        print("thread3:", data)
        self.startThread1.emit()

a = QtWidgets.QApplication(sys.argv)
app = MainUIClass()

a.setQuitOnLastWindowClosed(False)
app.setWindowTitle("Pyside2 thread compiled test")
app.show()

sys.exit(a.exec_())

推荐答案

每个环境中递归限制的设置可能不同.尝试调整递归限制

It is possible that there are different settings of recursion limit in each environment. Try to adjust the recursion limit

import sys
sys.setrecursionlimit(3000)

(3000只是一个猜测).您可以通过使用

(3000 is just a guess). You can see the limit by using

import sys
sys.getrecursionlimit()

这仅是一种破解,而不是推荐的方式.您应该考虑使用迭代而不是递归来重构代码,或者使递归更好地工作.很难提供所提供的信息.

This is only a hack, not a recommended way. You should think to refactor code using iteration instead of recursion or make the recursion work better. It's hard to tell more with provided information.

我已经看到其他人也设置了递归深度,例如:在python中设置stacksize脚本.也许也值得一试.

I've seen others setting also recursion depths like this: Setting stacksize in a python script . Maybe it's worth a try, too.

更新:更新问题后,我发现您还存在跟踪大小可变的问题.您也可以尝试:调整变量跟踪分配长度

UPDATE: After you have updated your question, I've seen that you also have problems with variable tracking size. You can also try that: Adjust Variable Tracking Assignment Length

这篇关于当我编译python代码时,我得到:RecursionError:调用Python对象时超出了最大递归深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆