Pygame - RuntimeError:调用Python对象时超出了最大递归深度

时间:2015-12-27 01:52:12

标签: python pygame

当我尝试运行我的代码时,我不断收到此错误:

RuntimeError: maximum recursion depth exceeded while calling a Python object

我很困惑为什么会发生这种情况,我试图制作一张图片blit并不断向下移动屏幕,作为玩家必须躲闪的对象,如果点击被“杀死”(仍然添加碰撞) 。当我开始得到错误时,使用以下命令对shell进行spams:

File "C:\Users\John\Desktop\Michael\V'Room External\GAME_MAIN_.py", line 195, in movement
    fallingObject()
File "C:\Users\John\Desktop\Michael\V'Room External\GAME_MAIN_.py", line 206, in fallingObject
    movement()
File "C:\Users\John\Desktop\Michael\V'Room External\GAME_MAIN_.py", line 160, in movement
    print(x)
File "C:\Python34\lib\idlelib\PyShell.py", line 1352, in write
    return self.shell.write(s, self.tags)
RuntimeError: maximum recursion depth exceeded while calling a Python object

相关代码是:

def movement():
    crashed = False
    while not crashed:
        print(x)
        ...
        if x < -10:
              x = -10
        else:
            if x > 490:
                x = 490
            else:
                fallingObject()



def fallingObject():
    global w
    w = 20
    global o_x
    o_x = random.randrange(0,width)
    objectSpawn = True
    while objectSpawn:
        movement()
    ...

3 个答案:

答案 0 :(得分:4)

问题是,在某些条件下,您的movement()方法会调用fallingObject(),然后调用movement()并调用fallingObject(),然后调用movement()然后调用fallingObject() def fallingObject(): ... movement() ... ...如果没有最大递归深度,他们会继续无限地互相呼叫。 Python检测到这种模式并关闭你的程序。无限递归总是很糟糕!

如果您查看方法的这些过度简化版本,您可以看到他们互相称呼:

def movement():
  ... 
  fallingObject()
  ...

movement()

由于代码中的条件,此行为并非始终发生,仅在-10 <= x <= 490时才会出现。

解决方案

你需要重新思考你的逻辑。你从另一个方法调用一个方法的原因是什么?

我实际上设法通过从fallingObject()移除def fallingObject(): ... while objectSpawn: movement() #<-delete this line ... objectSpawn = False 来电并进行其他一些更改来使您的计划有效。这是阻止无限递归的修改:

o_x = 0

从无限递归的角度来看,您已经删除了与代码无关的那些部分,但我仍然在这里写下您为使程序运行而必须做出的最重要的更改:

  1. 在程序开头定义这些变量:o_y = 0if o_y >= height,而不是在函数内使用global
  2. if o_y > height
  3. 中写fallingObject()而不是screen.blit(a, (o_x,o_y))
  4. 在您绘制carroad时执行fallingObject,否则蓝屏会隐藏掉落的物体

答案 1 :(得分:0)

只要movementobject_Spawnnot crashed

Truemovement就会相互致电。由于objectSpawncrashed被修改之前被调用,并且while仅在用户退出时被更改,因此它们将相互调用,直到您达到递归限制(默认为1000),其中,因为我在代码中看不到任何延迟或滴答率,所以会很快发生。

请注意,您还会在@Override public View getView(final int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { LayoutInflater layoutInflater = ((Activity) context).getLayoutInflater(); view = layoutInflater.inflate(R.layout.item_job_task, parent, false); // configure view holder JobTask_ViewHolder viewHolder = new JobTask_ViewHolder(); viewHolder.job_task_name = (EditText) view.findViewById(R.id.job_task_name); viewHolder.job_task_seekbar = (SeekBar) view.findViewById(R.id.job_task_seekbar); viewHolder.job_task_delete = (Button) view.findViewById(R.id.job_task_delete); view.setTag(viewHolder); Log.d("JobTasks_Adapter", "View was null" + view + " tag: " + viewHolder); } else { // this will give us address of the view Log.d("JobTasks_Adapter", "View was non-null" + view); } JobTask_ViewHolder viewHolder = (JobTask_ViewHolder) view.getTag(); Log.d("JobTasks_Adapter", "viewHolder address " + viewHolder); .... } 循环内发生这些调用。重构您的代码以使用这些循环运行游戏(您可能甚至不需要两者)而不是像这样进行递归调用。

答案 2 :(得分:0)

您的movement函数调用fallingObject,调用movement,创建一个递归循环。 Python限制你可以递归的深度(默认情况下为1000次),因此你需要重新组织逻辑以避免递归。

顺便说一句,你也应该尽量避免使用可修改的全局变量,因为它们使代码更少模块化,这使得调试和扩展程序变得更加困难。但是如果必须使用它们,则应将global语句放在需要它们的每个函数的开头。不要将它们分散到函数体中。

我还看到fallingObject有一个while循环,它总是运行一次。为什么呢?