【问题标题】:Pygame - RuntimeError: maximum recursion depth exceeded while calling a Python objectPygame - RuntimeError:调用 Python 对象时超出最大递归深度
【发布时间】:2016-04-01 07:46:37
【问题描述】:

每当我尝试运行我的代码时,我都会经常收到此错误:

RuntimeError: maximum recursion depth exceeded while calling a Python object

我对为什么会发生这种情况感到很困惑,我试图制作一个画面并不断向下移动屏幕,作为玩家必须躲避的对象,如果命中被“杀死”(仍然添加碰撞) .当我开始得到错误是垃圾邮件外壳:

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()
    ...

【问题讨论】:

标签: python pygame


【解决方案1】:

问题在于,在某些情况下,您的movement() 方法调用fallingObject(),然后它调用movement(),它调用fallingObject(),然后调用movement(),然后调用fallingObject()... 他们会继续调用如果没有最大递归深度,则彼此无限。 Python 检测到这种模式并关闭您的程序。无限递归总是不好的!

如果您查看这些过于简化的方法版本,您会发现它们相互调用:

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

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

由于代码中的条件,这种行为并不总是发生,只有在 -10

解决方案

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

实际上,我通过从fallingObject() 中删除movement() 调用并进行一些其他更改来使您的程序正常工作。这是防止无限递归的修改:

def fallingObject():
    ...   
    while objectSpawn:
        movement() #<-delete this line
        ...
        objectSpawn = False


你已经删除了那些从无限递归的角度来看无关紧要的代码部分,但我仍然在这里写下你必须做出的最重要的改变,以使你的程序工作:

  1. 在程序开头定义这些变量:o_x = 0,o_y = 0,而不是在函数内部使用全局变量
  2. fallingObject() 内写入if o_y &gt;= height 而不是if o_y &gt; height
  3. 在绘制 carroad 时执行 screen.blit(a, (o_x,o_y)),否则蓝屏会隐藏掉下的物体

【讨论】:

    【解决方案2】:

    fallingObjectmovement 相互调用,只要 object_Spawnnot crashedTrue。由于movement 在修改objectSpawn 之前调用,并且crashed 仅在用户退出时才更改,因此它们会互相调用,直到您达到递归限制(默认为1000),因为我没有看到代码中的任何延迟或滴答率都会很快发生。

    请注意,这些调用中的每一个都发生在 while 循环中。重构您的代码以使用这些循环运行游戏(您甚至可能不需要两者),而不是像这样进行递归调用。

    【讨论】:

      【解决方案3】:

      您的movement 函数调用fallingObject,它调用movement,创建一个递归循环。 Python 对递归的深度进行了限制(默认为 1000 次),因此您需要重新组织逻辑以避免这种递归。

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

      我还看到fallingObject 有一个始终只运行一次的while 循环。为什么?

      【讨论】:

        猜你喜欢
        • 2011-05-31
        • 2011-12-01
        • 2013-08-29
        • 1970-01-01
        • 2017-03-18
        • 2015-04-15
        • 2016-12-23
        • 2012-12-22
        • 1970-01-01
        相关资源
        最近更新 更多