AttributeError:NoneType对象没有属性'health'

Ove*_*ter 0 python debugging pygame

我在战略游戏Table Wars中进行了长时间的比赛,我得到了这个错误.只要战场上有很多单位,似乎就会发生这种情况.这是追溯:

Traceback (most recent call last):
  File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 727, in <module>
    main()
  File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 131, in main
RedTeam.update()
  File "C:\Python27\lib\site-packages\pygame\sprite.py", line 399, in update
for s in self.sprites(): s.update(*args)
  File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 372, in update
self.attack()
  File "C:\Users\Oventoaster\Desktop\Games\Table Wars\Table Wars.py", line 393, in attack
    self.target.health -= self.attack_damage
AttributeError: 'NoneType' object has no attribute 'health'
Run Code Online (Sandbox Code Playgroud)

例外似乎出现在定位和攻击代码中,因此我将在此处发布:

def move_toward(self, target):
    if self.target is None:
        self.rect.move_ip(1, 0)

def update(self):
    self.find_target()
    self.move_toward(self.target)
    self.attack()
    if self.health <= 0:
        self.kill()

def find_target(self):
    if self.target is not None: return
    for enemy in BluTeam.sprites():
        if enemy.rect.centerx - self.rect.centerx <= self.range and enemy.rect.centery - self.rect.centery <= self.range:
            self.target = enemy
            return
        self.target = None

def attack(self):
    global REDGOLD
    global BLUECOMMAND
    if self.target is None: return
    if self.target.health <= 0:
        REDGOLD += self.target.reward
        BLUECOMMAND += self.target.cmdback
        self.target = None
    if not self.cooldown_ready(): return
    self.target.health -= self.attack_damage

def cooldown_ready(self):
    now = pygame.time.get_ticks()
    if now - self.attack_last >= self.attack_cooldown:
        self.attack_last = now
        return True
    return False
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

Bou*_*oud 8

解释常见错误或如何更好地理解简单的回溯以调试我的程序:

  File "<path>\<filename>.py", line 393, in <function>
Run Code Online (Sandbox Code Playgroud)

Traceback为您提供了callstack并指出了函数中的错误引发.没什么特别的

    self.target.health -= self.attack_damage
Run Code Online (Sandbox Code Playgroud)

友好的解释器给出导致错误的声明.这很重要,因为它意味着引发的错误与这行代码有关.

AttributeError: 'NoneType' object has no attribute 'health'
Run Code Online (Sandbox Code Playgroud)

我们到了.错误是AttributeError; doc非常清楚:我正在尝试读取或者我正在尝试分配给不是相关对象成员的变量.

我的目标是什么?这是一个'NoneType' object; 我们没有这个名字,但我们有它的类型.我们遇到问题的对象是NoneType,因此它是特殊对象None.

这个None对象有什么错误?它没有'health'属性说是Traceback.因此,我们health在错误引发的代码行中的某处访问该属性,并在None对象上调用它.

现在,我们几乎所有的设置:self.target.health在我们使用错误行的唯一位置health,因此它的意思self.targetNone.现在我看一下源代码,我试着理解它为什么会这样,即使我在函数的开头对它进行检查.它导致我必须None在那条线后以某种方式设置它.


所有这些推理步骤都导致了简短的回答:

这意味着self.targetNone.错误来自您的代码:

if self.target.health <= 0:
    REDGOLD += self.target.reward
    BLUECOMMAND += self.target.cmdback
    self.target = None  # set to None
if not self.cooldown_ready(): return
self.target.health -= self.attack_damage  # self.target is None, .health failed
Run Code Online (Sandbox Code Playgroud)