Python课程学生管理系统NameError: 'StudentDetails'未定义报错排查
报错原因排查
- 核心问题:
StudentDetails类的定义位置不符合Python代码执行顺序要求
你将StudentDetails类写在了主逻辑while循环内部的if c==3分支中,只有menu()函数返回值为3时,类才会被定义。但你在menu()函数内部判断用户选3时就直接调用StudentDetails(),此时循环内的类定义分支还未执行,全局作用域中没有这个类,因此触发NameError。 - 附带其他隐性问题:
menu()函数没有设置返回值,你循环中判断c==3的分支永远不会触发StudentDetails类内部存在大量变量作用域错误、变量名错误,比如把列表student赋值为字符串后又调用append方法、未定义self.name等属性就直接打印、删除学生时调用不存在的name列表等- 菜单逻辑存在死循环风险,
menu()选1会递归调用自身,没有退出出口
修复方案
你可以按照以下步骤修改代码:
- 将
StudentDetails类移到全局作用域,放在diplomaProgramme类的后面,保证menu()调用时类已经完成定义 - 给
menu()函数添加返回值,补充退出逻辑 - 修正
StudentDetails类内部的变量错误,将学生存储列表改为全局变量或者类属性 - 调整菜单递归逻辑,避免栈溢出
修复后完整可运行代码
courses = ['Python Programming','Data Mining and Machine learning Course','Visual Analytics Course','Text Analytics Course'] # 新增全局学生存储列表 students = [] def menu():# 主菜单函数 print("1. 管理菜单") print("2. 课程详情") print("3. 学生详情") print("4. 退出") c=int(input("请输入您的选择:")) if c==2: diplomaProgramme() return "y" elif c==3: StudentDetails() return "y" elif c==1 : # 原逻辑递归调用menu会有栈溢出风险,这里改为直接返回y让外层循环重新调用 return "y" elif c==4: return "n" class diplomaProgramme(): def __init__(self): query = int(input('请填写所需输入\n添加课程请按1\n删除课程请按2\n退出程序请按3\n请输入您的选择:')) if query == 1: self.addCourse() elif query == 2: self.removeCourse() else: return def addCourse (self): course = input('请输入您要添加的课程名称:') courses.append(course) print('课程添加成功!') print('当前所有课程如下:', courses) q = int(input('请选择后续操作:\n返回上一级菜单请按1\n删除课程请按2\n请输入您的选择:')) if q == 2: self.removeCourse() else: return def removeCourse(self): print('当前所有课程如下:', courses) dcourse = input('请输入您要删除的课程名称:') if dcourse in courses: courses.remove(dcourse) print('课程删除成功!') else: print('您输入的课程不在学院开课范围内') q = int(input('请选择后续操作:\n返回上一级菜单请按1\n退出程序请按2\n请输入您的选择:')) if q == 1: return else: exit() # 移到全局作用域的StudentDetails类 class StudentDetails(): def __init__(self): query = int(input('请填写所需输入\n添加学生请按1\n删除学生请按2\n查看所有学生请按3\n返回主菜单请按4\n请输入您的选择:')) if query == 1: self.add_student() elif query == 2: self.removestudent() elif query ==3: self.show_all_students() else: return def add_student(self): name = input('请输入您要添加的学生姓名:') unique_id = input('请输入唯一ID:') signed_up_courses = input('请输入报名课程名称:') assignment_status = input('作业状态:') # 存储学生字典到全局列表 students.append({ "name":name, "unique_id":unique_id, "signed_up_courses":signed_up_courses, "assignment_status":assignment_status }) print('学生添加成功!') q = int(input('请选择后续操作:\n继续添加学生请按1\n删除学生请按2\n返回上一级请按3\n请输入您的选择:')) if q == 1: self.add_student() elif q == 2: self.removestudent() else: return def show_all_students(self): if not students: print("暂无学生数据") else: for idx,stu in enumerate(students,1): print(f"===== 第{idx}位学生 =====") print("姓名:"+stu['name']) print("唯一ID:"+stu['unique_id']) print("所选课程:"+stu['signed_up_courses']) print("作业状态:"+stu['assignment_status']) q = int(input('请选择后续操作:\n返回上一级请按1\n退出程序请按2\n请输入您的选择:')) if q ==1: self.__init__() else: exit() def removestudent(self): print('当前所有学生如下:', [stu['name'] for stu in students]) dname = input('请输入您要删除的学生姓名:') for stu in students: if stu['name'] == dname: students.remove(stu) print("学生删除成功") break else: print('该学生不在学院在册范围内') q = int(input('请选择后续操作:\n返回上一级菜单请按1\n退出程序请按2\n请输入您的选择:')) if q == 1: self.__init__() else: exit() c="y" while c=="y": c=menu()
内容的提问来源于stack exchange,提问作者Tarun Yadav
相关产品推荐
相关产品推荐

