首页 / 资讯中心 / 文章详情

Python学生管理系统实战:从增删查到数据持久化

Python学生管理系统实战:从增删查到数据持久化 ★ FEATURED ARTICLE
这个项目是一个命令行版本的学生管理系统主要实现新增学生 显示学生 查找学生 删除学生 存档到文件整个程序虽然不算复杂但是里面已经包含了一个完整小程序应该有的基本结构。一、先确定学生管理系统要做什么程序启动之后先显示一个菜单让用户选择操作。菜单可以设计成1. 新增学生信息 2. 显示所有同学信息 3. 根据名字查找学生信息 4. 删除学生信息 0. 退出程序然后不断读取用户输入根据不同的数字进入不同的功能。这种程序很适合使用whileTrue:让菜单一直运行。如果用户输入0直接退出程序。二、学生数据怎么保存这是写这个项目时我觉得最关键的一步。一个学生肯定不只是一个数据。比如一个学生至少有学号 姓名 性别 班级如果给每个学生都创建四个独立变量studentId...name...gender...className...学生一多就很难管理。所以这里可以使用字典表示一个学生。例如student{studentId:studentId,name:name,gender:gender,className:className}这样一个字典就表示一个完整的学生信息。三、多个学生怎么办一个学生用字典保存那多个学生就可以使用列表。程序中准备一个全局列表students[]每增加一个学生就把对应的字典放进去students.append(student)最终的数据结构其实就是students ↓ [ student1, student2, student3, ... ]其中每一个student又是一个字典。也就是列表 ↓ 多个字典 ↓ 每个字典保存一个学生的信息这种设计其实非常自然也把前面学到的list和dict结合起来了。四、创建程序入口程序可以设计一个main()作为入口函数。整体逻辑大概是defmain():whileTrue:choicemenu()ifchoice0:sys.exit()elifchoice1:insert()elifchoice2:show()elifchoice3:find()elifchoice4:delete()else:print(您的输入有误! 请重新输入!)最后再调用main()这样整个程序的组织结构就比较清楚了。main()不负责具体实现每一个功能而是负责“指挥”。真正的功能分别交给menu() insert() show() find() delete()去完成。五、菜单函数菜单本身单独封装成一个函数defmenu():print( 1. 新增学生)print( 2. 显示学生)print( 3. 查找学生)print( 4. 删除学生)print( 0. 退出程序)choiceinput( 请输入您的选择: )returnchoice把用户的输入交给main()判断。六、新增学生新增学生的流程比较简单输入学号 ↓ 输入姓名 ↓ 输入性别 ↓ 输入班级 ↓ 检查数据 ↓ 创建字典 ↓ 加入 students首先输入基本信息studentIdinput(请输入学生的学号: )nameinput(请输入学生的姓名: )genderinput(请输入学生的性别: )classNameinput(请输入学生的班级: )性别这里还进行了简单的检查ifgendernotin(男,女):print(性别输入的内容不符合要求, 新增失败!)return如果输入不符合要求就直接结束这次新增操作。之后创建学生字典student{studentId:studentId,name:name,gender:gender,className:className}最后students.append(student)把学生放进列表。七、显示所有学生有了students之后显示全部学生就很简单了。直接遍历forsinstudents:然后通过字典的 key 获取信息s[studentId]s[name]s[gender]s[className]例如可以按照学号 姓名 性别 班级这样的格式打印。最后还可以使用len(students)统计当前一共有多少条学生记录。这个功能实际上就是遍历列表 ↓ 访问字典 ↓ 输出数据八、根据姓名查找学生查找功能需要先让用户输入一个名字nameinput(请输入要查找的同学姓名: )然后遍历所有学生forsinstudents:检查ifnames[name]:如果匹配就把学生信息打印出来。同时使用count1记录一共找到了多少人。这里有一个实际开发中的小特点姓名不一定唯一。所以这里并没有找到第一个就结束而是把整个列表遍历完把所有同名学生都找出来。九、删除学生删除学生时采用学号进行查找。流程输入学号 ↓ 遍历 students ↓ 找到对应学生 ↓ 从列表中删除核心操作ifstudentIds[studentId]:students.remove(s)这里使用学号而不是姓名也是因为学号更加适合作为学生的唯一标识。十、为什么需要存档到目前为止程序虽然可以完成新增 显示 查找 删除但是还有一个很明显的问题程序一旦退出之前的数据就没了。因为现在的students[]本质上只是保存在程序运行期间的内存里。所以需要加入“存档”功能把学生信息保存到文件中。这里约定使用record.txt来保存学生数据。十一、设计存档文件的格式这里没有使用复杂的数据库而是直接使用文本文件。规定一个学生占一行 学生的不同信息之间使用 \t 分隔例如学号 名字 性别 班级这里的分隔符实际上是\t也就是制表符。这种格式非常简单但是对于这个小项目已经够用了。十二、实现保存函数保存函数可以写成defsave():withopen(record.txt,w,encodingutf-8)asf:forsinstudents:f.write(f{s[studentId]}\t{s[name]}\t{s[gender]}\t{s[className]}\n)print(f[存档成功] 共存储了{len(students)}条记录!)核心逻辑就是打开文件 ↓ 遍历 students ↓ 把每个学生写成一行 ↓ 关闭文件这里使用的是withopen(...)所以不需要手动写close()代码块结束之后文件会自动关闭。十三、什么时候保存数据在学生信息发生变化的时候就应该重新存档。也就是新增学生 ↓ save() 删除学生 ↓ save()这样程序的内存数据和文件中的数据就能保持更新。十四、重新启动程序还需要把数据读回来光有save()还不够。程序重新启动之后students[]还是一个空列表。所以启动的时候需要调用load()把文件中的数据重新恢复到students中。十五、读取存档文件读取数据时先判断文件存不存在ifnotos.path.exists(record.txt):return如果文件不存在就跳过读档。如果存在就students[]先准备一个空的学生列表。然后打开文件withopen(record.txt,r,encodingutf-8)asf:接下来逐行读取forlineinf:十六、把一行数据重新拆成学生信息存档的时候我们把数据用\t隔开。读档时就反过来把这一行重新拆开lineline.strip()tokensline.split(\t)如果拆出来的数据数量不足iflen(tokens)!4:print(f当前行格式存在问题! line{line})continue就说明这行数据格式有问题直接跳过。正常情况下tokens[0] → 学号 tokens[1] → 姓名 tokens[2] → 性别 tokens[3] → 班级然后重新构造字典student{studentId:tokens[0],name:tokens[1],gender:tokens[2],className:tokens[3]}再students.append(student)这样文件中的学生信息就重新恢复到内存中了。十七、整个数据流程把存档和读档放在一起看整个过程其实非常清晰。程序运行record.txt ↓ load() ↓ students ↓ 增 / 删 / 查 / 显示 ↓ save() ↓ record.txt也就是说文件 ↔ 程序内存之间形成了一个简单的数据同步过程。十八、为什么这里使用“列表 字典”这个数据结构其实非常适合这个项目。整体students[]学生列表里面保存student{studentId:...,name:...,gender:...,className:...}所以整体结构就是students │ ├── student │ ├── studentId │ ├── name │ ├── gender │ └── className │ ├── student │ ├── studentId │ ├── name │ ├── gender │ └── className │ └── ...列表解决“多个学生”的问题。字典解决“一个学生有多个属性”的问题。两者组合起来刚好满足需求。十九、完整代码把程序打包成exe# 实现一个命令行版本的学生管理系统importsysimportos.path# 使用这个全局变量, 来管理所有的学生信息# 这个列表的每个元素都是一个 字典, 每个字典就分别表示了一个同学students[]defsave(): 用于存档 withopen(record.txt,w,encodingutf-8)asf:forsinstudents:f.write(f{s[studentId]}\t{s[name]}\t{s[gender]}\t{s[className]}\n)print(f[存档成功] 共存储了{len(students)}条记录!)defload(): 用于读档 # 如果存档文件不存在, 则直接跳过读档流程# 为了避免读方式打开文件的时候, 文件不存在引起异常ifnotos.path.exists(record.txt):returnglobalstudents students[]withopen(record.txt,r,encodingutf-8)asf:forlineinf:lineline.strip()tokensline.split(\t)iflen(tokens)!4:print(f当前行格式存在问题! line{line})continuestudent{studentId:tokens[0],name:tokens[1],gender:tokens[2],className:tokens[3]}students.append(student)print(f[读档成功] 共读取了{len(students)}条记录)defmenu():print( 1. 新增学生)print( 2. 显示学生)print( 3. 查找学生)print( 4. 删除学生)print( 0. 退出程序)choiceinput( 请输入您的选择: )returnchoicedefinsert():print([新增学生] 开始!)studentIdinput(请输入学生的学号: )nameinput(请输入学生的姓名: )genderinput(请输入学生的性别: )ifgendernotin(男,女):print(性别输入的内容不符合要求, 新增失败!)returnclassNameinput(请输入学生的班级: )student{studentId:studentId,name:name,gender:gender,className:className}globalstudents students.append(student)save()print([新增学生] 完毕!)defshow():print([显示学生] 开始!)forsinstudents:print(f[{s[studentId]}]\t{s[name]}\t{s[gender]}\t{s[className]})print(f[显示学生] 完毕! 共显示了{len(students)}条数据!)deffind():# 根据学生姓名, 来进行查找print([查找学生] 开始!)nameinput(请输入要查找的同学姓名: )count0forsinstudents:ifnames[name]:print(f[{s[studentId]}]\t{s[name]}\t{s[gender]}\t{s[className]})count1print(f[查找学生] 结束! 共找到了{count}个匹配的同学!)defdelete():print([删除学生] 开始!)studentIdinput(请输入要删除的学生学号: )forsinstudents:ifstudentIds[studentId]:print(f删除{s[name]}同学的信息!)students.remove(s)save()print([删除学生] 结束!)defmain(): 入口函数 # 通过控制台和用户进行交互print(----------------------------------------------)print( 欢迎来到学生管理系统 )print(----------------------------------------------)load()whileTrue:# 通过 menu 函数来打印出菜单项choicemenu()ifchoice1:# 新增学生insert()elifchoice2:# 显示学生show()elifchoice3:# 查找学生find()elifchoice4:# 删除学生delete()elifchoice0:# 退出程序print(goodbye!)sys.exit(0)else:print(您的输入有误! 请重新输入!)continuemain()目前程序是一个.py文件。这种文件需要目标机器安装 Python 环境才能运行。为了方便部署可以使用PyInstaller把 Python 程序打包成.exe。首先安装pipinstallpyinstaller然后进行打包。其中-F表示打包成单个 exe。打包完成之后就可以把生成的程序复制到其他机器上使用而不需要再单独安装 Python 环境。二十、这个项目把哪些知识串起来了回头看一下这个学生管理系统里面其实已经用到了不少 Python 基础知识。函数 ↓ main / menu / insert / show / find / delete 列表 ↓ students 字典 ↓ student 条件语句 ↓ 菜单判断、数据合法性判断 循环 ↓ 菜单循环、遍历学生 文件 ↓ save / load 字符串 ↓ \t 分隔、split、strip 模块 ↓ sys、os 程序部署 ↓ PyInstaller所以这个项目虽然只是一个命令行学生管理系统但是已经不是单独练习某一个语法了而是开始尝试把多个知识点组合到一个完整程序中。二十一、总结这个学生管理系统最核心的地方我觉得不是“增删查”本身而是慢慢理解一个程序应该怎么组织。比如main()负责整个程序的流程。menu()负责菜单。insert() show() find() delete()分别负责具体的数据操作。save() load()负责数据持久化。这样每个函数各干各的事情整个程序看起来就不会乱。项目的基本结构也正是围绕这些函数展开的。如果只是在main()里面把所有代码全部写完刚开始可能还能看懂但功能一多很快就会变得非常混乱。所以我觉得这个项目真正值得记录的一点就是当程序开始变复杂之后不能只想着“把功能写出来”还要开始考虑怎么把代码组织起来。从一个简单的.py文件到能够完成增删查、保存数据、重新加载数据最后再打包成 exe这基本就是一次比较完整的 Python 小项目实践。
阅读完成 · 觉得有帮助?
咨询建站