Python OOP问题:调用Character类方法仅执行首个的原因排查
问题分析与修复方案
核心问题
- 属性未初始化引发崩溃:
Character类定义了两个__init__方法,后一个直接覆盖了前一个,导致swordsman、archer等核心属性在实例化时完全没被初始化。如果用户在选择角色类型时输入无效值,这两个属性不会被赋值,后续调用Set_Character_attack等方法时,访问self.archer或self.swordsman会直接抛出AttributeError,程序直接终止。 - 难度选择未传递:
Welcome_Message里创建的Game_Functions实例和display里的Character实例是完全独立的两个对象,难度选择的结果根本没传递给角色对象,导致后续根据self.dif判断属性的逻辑全部失效。 - 逻辑冗余且容错差:属性设置方法里的
or判断存在冗余(比如self.archer==True or self.swordsman==False,选弓箭手时两个条件都成立),而且初始的self.dif是空字符串,和True/False比较均为False,所有难度分支都不会执行。
修复后的代码
from random import randint class Game_Functions: def __init__(self): self.pop = "" self.dif = None # 初始化为None,明确未选择状态 def Set_Difficulty(self): while True: # 循环直到输入有效 self.pop = input("Please chose your difficulty (Easy/Hard): ") if self.pop.capitalize() == "Easy": print("You chose the easy difficulty") self.dif = True break elif self.pop.capitalize() == "Hard": print("You chose the hard difficulty") self.dif = False break else: print("Invalid Input, please enter Easy or Hard") class Character(Game_Functions): def __init__(self): super().__init__() # 调用父类初始化逻辑 # 提前初始化所有角色属性,避免未定义异常 self.swordsman = False self.archer = False self.health = 0 self.attack = 0 self.defense = 0 def Set_Character_type(self): while True: # 循环直到输入有效 message = input("Please Choose your Character type (Swordsman/Archer): ") if message.capitalize() == "Swordsman": self.swordsman = True self.archer = False print("You have chosen swordsman class") break elif message.capitalize() == "Archer": self.archer = True self.swordsman = False print("You have chosen archer class") break else: print("Invalid Input, please enter Swordsman or Archer") def Set_Character_health(self): if self.dif is None: print("Please select difficulty first!") return if self.archer: self.health = randint(1, 12) if self.dif else randint(1, 6) elif self.swordsman: self.health = randint(1, 18) if self.dif else randint(1, 9) print("The character's health is", self.health) def Set_Character_attack(self): if self.dif is None: print("Please select difficulty first!") return if self.archer: self.attack = randint(6, 24) if self.dif else randint(3, 14) elif self.swordsman: self.attack = randint(12, 17) if self.dif else randint(6, 9) print("The character's attack is", self.attack) def Set_Character_defense(self): if self.dif is None: print("Please select difficulty first!") return if self.archer: self.defense = randint(5, 10) if self.dif else randint(2, 6) elif self.swordsman: self.defense = randint(4, 11) if self.dif else randint(3, 8) print("The character's defense is", self.defense) def main(): # 用单个Character实例完成所有流程,保证难度参数能被共享 player = Character() player.Set_Difficulty() player.Set_Character_type() player.Set_Character_health() player.Set_Character_attack() player.Set_Character_defense() if __name__ == "__main__": main()
修复说明
- 合并实例传递难度:改用单个
Character实例完成难度选择和角色创建,确保难度参数能被所有属性方法访问。 - 提前初始化属性:在
Character的构造方法里初始化所有角色属性,彻底避免未定义属性引发的崩溃。 - 循环校验输入:给难度和角色类型添加循环输入逻辑,直到用户输入有效内容,避免无效输入中断流程。
- 简化逻辑判断:去掉冗余的
or判断,直接根据角色类型的布尔值分支,代码更简洁易懂。 - 增加状态检查:在属性设置方法里检查难度是否已选择,避免未选难度就执行属性逻辑。
内容的提问来源于stack exchange,提问作者Bradkik
相关产品推荐
相关产品推荐

