概述
目录
需求概述
新的一个学期开始了,开学的第一天辅导员找到你,说班里学生太多,想让你帮着做一个学生管理系统。
你一想这不是很简单,
啪啪啪敲下了几行代码便交了上去。
# 用数据与字典结合的形式保存数据
data = []
while True:
inp = input('请输入新增、查看或退出:n')
if inp == '新增':
# 接收用户数据,并去除前后空格
inp = input('输入姓名、性别、年龄,用空格作区分:n').strip()
name, gender, age = inp.split(' ')
# 将数据拆分出来并以字典形式添加到数组中
data.append(
dict(
name=name,
gender=gender,
age=age,
)
)
elif inp == '查看':
print('当前共有%s名学生' % len(data))
# 循环打印数据
for item in data:
print(
'姓名:{name},性别:{gender},年龄:{age}'.format(
name=item['name'], gender=item['gender'], age=item['age']
)
)
elif inp == '退出':
break
else:
print('输入错误请重新输入')
print('n')
你运用了之前所学到的知识,使用了列表与字典类型保存数据。
使用了 while 循环接收用户的操作, 用 input 接收输入并对其字符串拆分。
pickle 序列化
美美地等着辅导员夸奖的你,等来了辅导员的电话,他告诉你他花半小时录入的数据在重启程序后消失,
你一拍腿大呼忘记将其持久化到硬盘,于是便运用了上个章节学到的文件操作进行修改。
因为文件的操作写入时接收二进制或字符串类型,便需要将我们数组与字典组合的类型序列化成字符串加以保存。
什么是序列化?
序列化便是以一定规范将对象转成二进制或字符,等到需要时再将其解析回对象。
常在需要保存对象到文件或数据库,再或者网络传输时使用。
在这里我们使用内置的pickle模块来序列化和反序列化。
import os
import pickle
# 用大写变量名来表示一些常量
DATA_PATH = './data'
# 用数据与字典结合的形式保存数据
data = []
# 判断文件是否存在
if os.path.exists(DATA_PATH):
with open(DATA_PATH, 'r') as f:
data_str = f.read()
data = pickle.loads(data_str)
while True:
inp = input('请输入新增、查看或退出:n')
if inp == '新增':
# 接收用户数据,并去除前后空格
inp = input('输入姓名、性别、年龄,用空格作区分:n').strip()
name, gender, age = inp.split(' ')
# 将数据拆分出来并以字典形式添加到数组中
data.append(
dict(
name=name,
gender=gender,
age=age,
)
)
elif inp == '查看':
print('当前共有%s名学生' % len(data))
# 循环打印数据
for item in data:
print(
'姓名:{name},性别:{gender},年龄:{age}'.format(
name=item['name'], gender=item['gender'], age=item['age']
)
)
elif inp == '退出':
break
else:
print('输入错误请重新输入')
print('n')
with open(DATA_PATH, 'w') as f:
f.write(pickle.dumps(data))
我们运用之前学到的知识,在一开始读取文件并用 loads 将二进制解析成数组。
并在之后退出程序时将 data 数组 dumps 成二进制。
在你刚写完的时候,辅导员来了电话,说他还需要更新数据功能。
你一寻思,辅导员是典型的甲方心态。一开始自己心里没个数,一会说加个功能,一会说修改个功能。
代码经常修改的话, 会影响到开发封闭原则,各模块相互引用如盘丝洞般错综复杂,不小心就变成了屎山。
所以你想到了可以面向对象的方式重构代码,面向对象的三大特征是抽象、继承、多态,可以让你很容易地应对之后的修改与功能的新增。
面向对象设计是对付不合理甲方的神器。
首先我们确定三个类。
class Student:
# 学生对象
def __init__(self, name, gender, age):
pass
def __str__(self):
# 打印时的显示
pass
class Op:
# 所有操作类的父类
@staticmethod
def hander(data):
raise NotImplementedError()
class Manager:
# 负责程序的管理,数据的读取与保存
def register(self, op):
# 注册操作
pass
def unregister(self, op):
# 取消注册
pass
def load(self):
# 从文件读取数据
pass
def save(self):
# 保存数据到文件
pass
def loop(self):
# 执行循环
pass
以上就是我们大致定义到的接口,针对其分别进行实现。
import os
import pickle
DATA_PATH = './data'
class Student:
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age
def __str__(self):
return '姓名:{name},性别:{gender},年龄:{age}'.format(
name=self.name, gender=self.gender, age=self.age
)
class Op:
action = ''
@staticmethod
def handle(data):
raise NotImplementedError()
class Manager:
ops = {}
data = []
def __init__(self):
self.load()
def load(self):
# 从文件读取数据
# 判断文件是否存在
if os.path.exists(DATA_PATH):
with open(DATA_PATH, 'rb') as f:
data_str = f.read()
if data_str:
self.data = pickle.loads(data_str)
def save(self):
# 保存数据到文件
with open(DATA_PATH, 'wb') as f:
f.write(pickle.dumps(self.data))
def register(self, op):
# 注册操作
self.ops[op.action] = op
def unregister(self, op):
# 取消注册
if op.action in self.ops:
self.ops[op.action]
def loop(self):
# 执行循环
while True:
inp = input(
'请输入%s或退出:n' % ','.join([action for action in self.ops.keys()])
)
if inp == '退出':
break
if inp in self.ops:
self.ops[inp].handle(self.data)
else:
print('输出错误')
self.save()
我们完成了以上的东西, 这时我们定义一个 OpAdd 类 与 OpList 继承自 Op 类。
并将其注册到 manager 中,运行我们的程序。
class OpAdd(Op):
action = '增加'
@staticmethod
def handle(data):
inp = input('输入姓名、性别、年龄,用空格作区分:n')
name, gender, age = inp.split(' ')
data.append(Student(name, gender, age))
print('增加成功')
return data
class OpList(Op):
action = '查看'
@staticmethod
def handle(data):
print('当前共有%s名学生' % len(data))
# 循环打印数据
for student in data:
print(student)
manager = Manager()
manager.register(OpAdd)
manager.register(OpList)
# 执行
manager.loop()
到此完成了我们的程序,测试一下!
请输入增加,查看或退出:
增加
输入姓名、性别、年龄,用空格作区分:
小明 男 20
增加成功
请输入增加,查看或退出:
增加
输入姓名、性别、年龄,用空格作区分:
鸣人 男 18
增加成功
请输入增加,查看或退出:
查看
当前共有2名学生
姓名:小明,性别:男,年龄:20
姓名:鸣人,性别:男,年龄:18
请输入增加,查看或退出:
退出
练习
1.甲方的需求是无止尽的,完善上面的程序!
增加删除功能
增加按名字搜索功能
解析
1.甲方的需求是无止尽的,完善上面的程序!
增加删除功能
增加按名字搜索功能
class OpDel(Op):
action = '删除'
@staticmethod
def handle(data):
inp = input('输入要删除的姓名:n')
for student in data:
if student.name == inp:
data.remove(student)
print('删除了:%s' % student)
class OpSearch(Op):
action = '搜索'
@staticmethod
def handle(data):
inp = input('输入要搜索的姓名:n')
for student in data:
if inp in student.name:
print('搜索到:%s' % student)
最后
以上就是忧心发夹为你收集整理的python 管理系统详解_自学计划 - python 小白基础教程 - 第十二课:学生管理系统...的全部内容,希望文章能够帮你解决python 管理系统详解_自学计划 - python 小白基础教程 - 第十二课:学生管理系统...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复