调用python obj时超过了最大递归深度

2024-04-28 09:43:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是实例化一个名为arrow的类,这样我就可以有更多的箭头,而不是1。我想从坐标200开始,每100毫秒增加15个x。但当我尝试执行此代码时,它会给出以下错误:

  File "game.py", line 25, in moveArrow
    self.after(100, self.moveArrow(arrow, xCoord+15, yCoord)) #repeat, changing x
  File "game.py", line 24, in moveArrow
    arrow.place(x = xCoord, y = yCoord) #replace with new x,y
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1860, in place_configure
    + self._options(cnf, kw))
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1055, in _options
    elif isinstance(v, (tuple, list)):
RuntimeError: maximum recursion depth exceeded while calling a Python object

“File”game.py“,第25行,在move Arrow self.after(100,self.moveArrow(Arrow,xCoord+15,yCoord))中,重复,更改x“也经常重复。

from Tkinter import *
from random import randint
from PIL import ImageTk, Image

class App(Frame):
        def __init__(self, master=None):
                Frame.__init__(self, master, height=400, width=400)
                self.master = master
                self.master.bind('<Shift_L>', self.createArrow)
        def createArrow(self, event):
                self.arrow = Arrow(self)
                self.arrow.moveArrow(self.arrow, 200, 200)

class Arrow(Frame):
        def __init__(self, master):
                Frame.__init__(self, master)
                self.arrowImage = ImageTk.PhotoImage(Image.open("arrow.gif"))
                Label(self, image=self.arrowImage).pack()
        def moveArrow(self, arrow, xCoord, yCoord):
                arrow.place_forget()
                arrow.place(x = xCoord, y = yCoord)
                self.after(100, self.moveArrow(arrow, xCoord+15, yCoord))

root = Tk()
root.title("Mein erstes Spiel")
app = App(master=root).pack()
root.mainloop()

Tags: inpyselfmasterlibdeflineplace
3条回答

您正在调用self.moveArrow(arrow, xCoord+15, yCoord)内部的moveArrow()方法。

所以在任何阶段都有一个没有break的无止境递归。 如果您想了解如何构建python递归方法,可以阅读here

如果你想创建一些简单的移动效果,那么就在一个循环上做,假设你在x+200和y+200处移动箭头,生成一个简单的for循环并延迟移动箭头。

伪代码示例:

def moveArrow(....)
    loop:
        x += 10
        y += 10
        change_arrow_place(...)

产生问题的行是

self.after(100, self.moveArrow(arrow, xCoord+15, yCoord))x

因为moveArrow没有中断条件。当我们在编程语言中使用递归时,递归需要break条件,从这里它将不再调用同一个函数。

例如:递归中的素数

int isPrime(int num,int i){

    if(i==1){
        return 1;
    }else{
       if(num%i==0)
         return 0;
       else
         isPrime(num,i-1);
    }
}

在上面的代码中断条件是if (i==1)if(num%i==0)在这两个条件下,它不会调用isPrime函数,递归将在那里终止。

请添加中断条件并再次运行。

其他答案是正确的,问题的根源是这一行:

self.after(100, self.moveArrow(arrow, xCoord+15, yCoord))

但答案是Tkinter特有的:

查看^{}方法的文档,了解如何正确实现此方法。像普通的函数调用一样调用它将做到这一点,并在控制流到达该函数调用时将程序放入无限循环中。使用after时,有两个选项:

传递时间参数,然后是回调,然后是回调参数:

self.after(100, self.moveArrow, arrow, xCoord+15, yCoord)

或者,使用lambda表达式保存函数调用:

self.after(100, lambda: self.moveArrow(arrow, xCoord+15, yCoord))

相关问题 更多 >