pyglet游戏开发报错:'Player'对象无'radius'属性AttributeError排查
问题原因
这个报错和缩进无关,是初始化顺序逻辑错误,从报错回溯就能直接定位根因:
- 你在
Player.__init__中先调用super().__init__(...)执行父类Entity的初始化逻辑 - 父类
Entity.__init__最后一行会创建HitBox实例,而HitBox.__init__中会立刻调用传入entity对象的getWidth()方法 - 此时
Player.__init__里super()调用之后的代码(也就是给self.radius、self.speed等属性赋值的代码)完全没有执行,self.radius属性还不存在,自然会抛出属性不存在的错误。
你提到的tick、getShape等方法能正常访问self.radius,是因为这些方法调用时Player实例早就初始化完成,self.radius已经赋值完毕,自然不会报错。
解决方法
两种常用改法选其一即可:
- 方法一(改动最小,推荐):把Player类自身属性的赋值逻辑移到
super().__init__调用之前。radius是Player自身的属性,提前赋值不会和父类逻辑冲突,修改后的__init__示例:def __init__(self, name, x, y, handler, dN=False): # 先给子类自身属性赋值 self.speed = 2 self.radius = 5 self.direction = (0, 0) # 再执行父类初始化,此时父类初始化HitBox调用getWidth/Height时就能正常读取radius值 super().__init__(name, x, y, handler, dN) - 方法二:把父类中创建HitBox的逻辑从
__init__中拆分出来,做成单独的后置初始化方法,等子类所有属性赋值完成后再调用,比如给Entity加_init_hitbox方法,在子类__init__末尾手动调用,或者由EntityManager在添加实体时统一初始化hitbox,避免操作未完成初始化的半实例对象。
内容的提问来源于stack exchange,提问作者noah1400
相关产品推荐
相关产品推荐

