Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调用python对象时超出了最大递归深度_Python_Tkinter - Fatal编程技术网

调用python对象时超出了最大递归深度

调用python对象时超出了最大递归深度,python,tkinter,Python,Tkinter,我的目标是实例化一个名为arrow的类,这样我就可以拥有比1更多的arrow。我想从坐标200200开始,每100毫秒增加x 15。但当我尝试执行此代码时,它会给我以下错误: 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的类,这样我就可以拥有比1更多的arrow。我想从坐标200200开始,每100毫秒增加x 15。但当我尝试执行此代码时,它会给我以下错误:

  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
移动箭头self.after(100,self.moveArrow(Arrow,xCoord+15,yCoord))#repeat,changing x“中的第25行“File”game.py也经常重复

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()
从Tkinter导入*
从随机导入randint
从PIL导入ImageTk,图像
类应用程序(框架):
def uuu init uuu(self,master=None):
帧。u_初始__;(自,主,高度=400,宽度=400)
self.master=master
self.master.bind(“”,self.createArrow)
def createArrow(自身,事件):
self.arrow=箭头(self)
self.arrow.moveArrow(self.arrow,200200)
类箭头(框架):
定义初始(自我,主):
帧。\uuuu初始化(自,主)
self.arrowImage=ImageTk.PhotoImage(Image.open(“arrow.gif”))
标签(self,image=self.arrowImage).pack()
def移动箭头(self、arrow、xCoord、yCoord):
arrow.place_忘记()
箭头位置(x=xCoord,y=yCoord)
self.after(100,self.moveArrow(arrow,xCoord+15,yCoord))
root=Tk()
根标题(“Mein erstes Spiel”)
app=app(master=root).pack()
root.mainloop()

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

因此,在任何阶段都有一个无休止的递归,没有中断。 如果您想了解如何构建python递归方法,可以阅读

如果您想创建一些简单的移动效果,那么只需在一个循环上执行,假设您在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))
但答案是具体的:

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

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

self.after(100, self.moveArrow, arrow, xCoord+15, yCoord)
或者,使用lambda表达式保存函数调用:

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

这绝对是在tkinter中制作动画的错误方法。你永远不应该在GUI中调用
sleep
。@Bryan Oakley你是对的,因为睡眠会冻结整个GUI,这只是一个例子。@KobiK:如果你知道这是错误的方法,你不应该给出一个例子。在我写这篇评论时,这是公认的答案。因此,提出问题的人认为这是正确的方法,并将学会一种不正确的编写代码的方法。@Bryan Oakley问题是不间断的递归,与睡眠无关,我将删除睡眠部分,因为你的评论是正确的。@KobiK:问题是递归,但不是因为没有休息。问题是首先存在递归。正确调用
之后的
时,不存在递归。这个答案有正确的解释:你对这行的解释是正确的,你对解释的解释是错误的。如果你能解释我在解释中什么是错误的,那么我的观点也会很清楚:)正确的解释在这个答案中:。问题与需要“中断”条件无关。问题在于如何在调用
后调用
。感谢@BryanOakley的回复。这里有很多好信息:。。。除此之外,只要做点东西,你就会明白的