python 管理系统详解_自学计划 - python 小白基础教程 - 第十二课:学生管理系统...

目录

需求概述

新的一个学期开始了,开学的第一天辅导员找到你,说班里学生太多,想让你帮着做一个学生管理系统。

你一想这不是很简单,

啪啪啪敲下了几行代码便交了上去。

# 用数据与字典结合的形式保存数据

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值