You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:25:19