Python代码报错:列表中找不到指定变量,求调试帮助
问题修复:ValueError: 'Math' is not in list
错误原因分析
- 核心报错原因:
sub_avg方法中调用self.subjects.index(subject)时,传入的是字符串(如"Math"),但self.subjects列表存储的是Subject对象。index方法直接对比元素本身,字符串与Subject对象无法匹配,因此抛出找不到元素的错误。 - 其他潜在问题:
student_avg方法中使用self.subjects.len(),正确写法应为len(self.subjects)(列表无len()方法,需用内置函数len())。__lt__和__gt__魔术方法返回字符串,不符合Python规范(此类方法需返回布尔值),会导致比较操作异常。Grade类初始化时,参数不合法仅打印提示但未阻止对象创建,后续调用get_val/get_weight会引发AttributeError。
修复方案
1. 修复sub_avg方法
遍历科目列表,通过name属性匹配目标科目,替代index方法:
def sub_avg(self, subject_name): for subj in self.subjects: if subj.name == subject_name: return subj.avg() raise ValueError(f"Subject '{subject_name}' not found")
2. 修复student_avg方法
修正列表长度的获取方式:
def student_avg(self): if not self.subjects: return 0.0 summ = 0 for subject in self.subjects: summ += subject.avg() return summ / len(self.subjects)
3. 修正魔术方法__lt__和__gt__
让方法返回布尔值,符合Python魔术方法规范:
def __lt__(self, other): if not isinstance(other, Subject): raise TypeError("Can only compare with Subject instances") return self.avg() < other.avg() def __gt__(self, other): if not isinstance(other, Subject): raise TypeError("Can only compare with Subject instances") return self.avg() > other.avg()
4. 完善Grade类参数校验
参数不合法时抛出异常,避免生成无效对象:
def __init__(self, grade_val, grade_weight): if grade_weight > 4 or grade_weight < 1 or grade_val > 100 or grade_val < 0: raise ValueError("Grade weight must be between 1-4, grade value must be between 0-100") self.grade_value = grade_val self.grade_weight = grade_weight
完整修复代码
class Grade: def __init__(self, grade_val, grade_weight): if grade_weight > 4 or grade_weight < 1 or grade_val > 100 or grade_val < 0: raise ValueError("Grade weight must be between 1-4, grade value must be between 0-100") self.grade_value = grade_val self.grade_weight = grade_weight def get_val(self): return self.grade_value def get_weight(self): return self.grade_weight class Subject: def __init__(self, subject_name): self.name = subject_name self.grades = [] def add_grade(self, grade): if not isinstance(grade, Grade): raise TypeError("Input must be a Grade instance") self.grades.append(grade) def avg(self): if not self.grades: return 0.0 counter = 0 grade_sum = 0 for grade in self.grades: grade_sum += grade.get_val() * grade.get_weight() counter += grade.get_weight() return grade_sum / counter def __str__(self): grades_str = "" for grade in self.grades: grades_str += f"Val: {grade.get_val()} Weight: {grade.get_weight()}. " return grades_str def __len__(self): return len(self.grades) def __lt__(self, other): if not isinstance(other, Subject): raise TypeError("Can only compare with Subject instances") return self.avg() < other.avg() def __gt__(self, other): if not isinstance(other, Subject): raise TypeError("Can only compare with Subject instances") return self.avg() > other.avg() class Student: def __init__(self, name, s_id): self.name = name self.id = s_id self.subjects = [] def add_sub(self, subject): if not isinstance(subject, Subject): raise TypeError("Input must be a Subject instance") self.subjects.append(subject) def add_grade(self, subject_name, grade): if not isinstance(grade, Grade): raise TypeError("Input must be a Grade instance") for subj in self.subjects: if subj.name == subject_name: subj.add_grade(grade) return raise ValueError(f"Subject '{subject_name}' not found") def get_subs(self): return self.subjects def sub_avg(self, subject_name): for subj in self.subjects: if subj.name == subject_name: return subj.avg() raise ValueError(f"Subject '{subject_name}' not found") def student_avg(self): if not self.subjects: return 0.0 summ = 0 for subject in self.subjects: summ += subject.avg() return summ / len(self.subjects) std = Student("Ofek", 42069) std.add_sub(Subject("Math")) std.add_grade("Math", Grade(98, 4)) std.add_grade("Math", Grade(92, 2)) std.add_sub(Subject("English")) std.add_grade("English", Grade(85, 3)) print(std.sub_avg("Math")) print(std.student_avg())
运行结果
96.0 90.5
内容的提问来源于stack exchange,提问作者happymancer
相关产品推荐
相关产品推荐

