用python实现学生管理系统

时间:2022-08-24 18:12:01

学生管理系统

相信大家学各种语言的时候,练习总是会写各种管理系统吧,管理系统主要有对数据的增删查改操作,原理不难,适合作为练手的小程序

数据的结构

要保存数据就需要数据结构,比如c里面的结构体啊,python里面的列表,字典,还有类都是常用的数据类型
在这里,我使用了链表来作为学生数据的数据结构,
即 Node类 和 Student_LinkList类,来实现链表

数据的持久化

我们在程序中产生的数据是保存在内存中的,程序一旦退出,下次就不能恢复此次的数据了,因此需要把内存种的数据,保存到文件或数据库中,存储起来,这个过程就叫数据的持久化

本程序使用了python标准库pickle提供的序列化方法dump()和load()来实现数据的持久化

配置文件

使用配置文件,可以方便程序中使用不同的子类实现,

本程序使用configparser来对配置文件解析
本程序配置文件名为 Student.ini

?
1
2
3
4
5
6
7
#Student.ini文件
[Student]
student = Student_LinkList
 
[Persistence]
persistence = Persistence_Pickle
file = student.pik

类之间的关系

Student #和学生数据有关的抽象类
±- Student_LinkList
Persistence #和持久化有关的抽象类
±- Persistence_Pickle
MyConfigure #和配置文件读取有关的类
UI #和交互有关的父类
±- Cmd_UI

界面预览

用python实现学生管理系统

源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
'''
使用单链表实现的学生管理系统
'''
import pickle
import abc
import configparser
 
class Student(abc.ABC):
 '''
 抽象学生类
 '''
 @abc.abstractmethod
 def add(self):
  '''
  增加学生结点
  '''
  pass
 
 @abc.abstractmethod
 def ladd(self):
  '''
  从左侧增加学生结点
  '''
  pass
 
 @abc.abstractmethod
 def delete(self,id_):
  '''
  根据id值来删除一个结点
  '''
  pass
 
 @abc.abstractmethod
 def delete_name(self,name):
  '''
  根据姓名来删除一个结点
  '''
  pass
 
 @abc.abstractmethod
 def insert(self,idx,val):
  '''
  插入到指定的位置
  '''
  pass
 
 @abc.abstractmethod
 def show(self):
  '''
  显示所有的学生结点
  '''
  pass
 
 @abc.abstractmethod
 def search_id(self):
  '''
  根据id查询节点
  '''
  pass
 
 @abc.abstractmethod
 def search_name(self):
  '''
  根据name查询节点
  '''
 
 @abc.abstractmethod
 def modity_id(self):
  '''
  根据id找到节点,然后修改
  '''
  pass
 
 
 
class Node(object):
 '''
 学生链表结点
 '''
 def __init__(self,id_: int,name: str,sex: str,age: int,score: int):
  self.id = id_
  self.name = name
  self.sex = sex
  self.age = age
  self.score = score
 
  self.next = None
 
 def modity(self,id_,name,sex,age,score):
  '''
  修改
  '''
  self.id = id_
  self.name = name
  self.sex = sex
  self.age = age
  self.score = score
 
 
 def __str__(self):
  '''
  用于显示输出
  '''
  return f"[学生:{self.id:^2}]-->name:{self.name:^10}sex:{self.sex:^10}age:{self.age:^10}score:{self.score:^10}"
 
class Student_LinkList(Student):
 '''
 学生链表
 '''
 def __init__(self):
  self.head = Node(-1,'head','-1',-1,-1)
  self.length = 0
  self.tail = self.head #尾部结点用于尾插
 
 def add(self,id_,name,sex,age,score):
  '''
  添加一个学生结点,尾插
  '''
  #print('当前tail的值',self.tail)
  temp = Node(id_,name,sex,age,score)
  self.tail.next = temp
  self.tail = self.tail.next
 
  self.length += 1
  print('[info]:添加成功')
 
 def ladd(self,id_,name,sex,age,score):
  '''
  添加一个学生,头插
  '''
  temp = Node(id_,name,sex,age,score)
  temp.next = self.head.next
  self.head.next = temp
 
  if self.tail == self.head:
   self.tail = temp
 
  self.length += 1
  print('[info]:添加成功')
 
 def delete(self,id_):
  '''
  根据id值来删除一个结点,用迭代实现
  '''
  p = self.head
  while p.next != None and p.next.id != id_:
   p = p.next
 
  if p.next == None:
   print('[error]:找不到id')
   return -1
  else:
   temp = p.next
   p.next = temp.next
   #如果删除的是尾结点,还要移动tail
   if temp.next == None:
    self.tail = p
   del temp
  print('[info]:删除成功')
 
 def delete_name(self,name):
  '''
  根据姓名来删除一个结点,用递归实现
  '''
  def _func(node: Node,name: str):
   '''
   递归函数
   '''
   #到了尾巴节点了,还没有找到
   if node.next == None:
    print('[info]:找不到name')
    return False
   elif node.next.name == name:
    temp = node.next
    node.next = temp.next
    #如果删除的是尾结点,还要移动tail
    if temp.next == None:
     self.tail = node
    del temp
    print('[info]:删除成功')
    return True
   else:
    return _func(node.next,name)
 
  t = self.head
  return _func(t,name)
 
 def insert(self,idx,id_,name,sex,age,score):
  '''
  在指定位置插入数据
  '''
  if idx > self.length or idx == 0:
   print(f'[error]:你输入的索引非法(1-{self.length})')
   return 0
  p,cur = self.head,0
  while p != None and cur < idx-1:
   p = p.next
 
  if cur < idx-1:
   return -1
  else:
   temp = Node(id_,name,sex,age,score)
   temp.next = p.next
   p.next = temp
   return True
  print('[info]:插入成功')
 
 def search_id(self,id_):
  '''
  根据id查询节点
  '''
  p = self.head
  while p != None and p.id != id_:
   p = p.next
  if p == None:
   return -1
  else:
   return p
 
 def search_name(self,name):
  '''
  根据name查询节点
  '''
  p = self.head
  
  def _func(node: Node,name: str):
   '''
   递归函数
   '''
   if node == None:
    return -1
   elif node.name == name:
    return node
   return _func(node.next,name)
 
  return _func(p,name)
 
 def modity_id(self,id0,id_,name,sex,age,score):
  '''
  根据id找到节点,然后修改
  '''
  node = self.search_id(id0)
  if node == -1:
   print('[error]:找不到该id')
   return -1
  else:
   node.modity(id_,name,sex,age,score)
 
 
 def show(self):
  '''
  显示所有的学生结点,迭代
  '''
  print(f'\n{"-"*25}以下是系统内数据{"-"*25}')
  temp = []
  p = self.head
  while p != None:
   temp.append(p)
   p = p.next
  return temp
 
class Student_Array():
 '''
 用数组实现学生数据存储
 '''
 pass
 
class Student_Queue():
 '''
 用队列实现
 '''
 pass
 
class Student_Dict():
 '''
 用队列实现
 '''
 pass
 
class Persistence(abc.ABC):
 '''
 链表数据的持久化
 '''
 @abc.abstractmethod
 def save(self):
  '''
  把对象保存
  '''
  pass
 
 @abc.abstractmethod
 def load(self):
  '''
  加载对象
  '''
  pass
 
class Persistence_Pickle(Persistence):
 '''
 使用pickle来序列化
 '''
 def __init__(self,cls: Student,file_):
  self.filename = file_
  self.obj = None
  self.cls = cls
 
 def save(self):
  with open(self.filename,'wb') as f:
   pickle.dump(self.obj,f)
 
 def load(self):
  try:
   with open(self.filename,'rb') as f:
    temp = pickle.load(f)
  except:
   temp = globals()[self.cls]()
  print('返回temp:',type(temp))
  self.obj = temp
  return temp
 
class Persistence_File(Persistence):
 '''
 使用文件来持久化
 '''
 pass
 
class Persistence_Mysql(Persistence):
 '''
 使用Mysql数据库来持久化
 '''
 pass
 
class Persistence_Socket(Persistence):
 '''
 使用远程套接字持久化
 '''
 pass
 
class MyConfigure(object):
 '''
 用来读取配置文件的类
 '''
 def __init__(self):
  self.config = configparser.ConfigParser()
 
 def save(self):
  '''
  保存配置文件
  '''
  with open('Student.ini','w') as f:
   self.config.write(f)
 
 def load(self):
  '''
  加载配置文件
  '''
  self.config.read('Student.ini')
 
 def get_student_class(self):
  '''
  获得Student该使用哪个子类
  '''
  return self.config['Student']['student']
 
 def get_persistence_class(self):
  '''
  获得持久化,该使用那个类,
  如果是Pickle或文件,还有file作为保存的文件名
  '''
  temp = {}
  temp['persistence'] = self.config['Persistence']['persistence']
  if 'Persistence_Pickle' in temp['persistence']:
   temp['file'] = self.config['Persistence']['file']
  return temp
 
class UI(object):
 '''
 界面交互
 '''
 def __init__(self):
  self.config = MyConfigure()
  self.config.load()
  s_class = self.config.get_student_class()
  p_class = self.config.get_persistence_class()
 
  self.persistence = globals()[p_class['persistence']](s_class,p_class['file'])
  self.student = self.persistence.load()
  print('实例化成功:',self.student,self.persistence)
 
 def save(self):
  '''
  把数据保存
  '''
  self.persistence.save()
 
 def quit(self):
  '''
  退出:先保存配置,然后退出
  '''
  self.config.save()
  self.save()
 
 def _show(self):
  '''
  显示所有学生节点
  '''
  return self.student.show()
 
 
 def _add(self,direction,*temp):
  '''
  增加学生结点,
  direction 1左添加,2右添加
  '''
  if direction == 1:
   self.student.ladd(*temp)
  elif direction == 2:
   self.student.add(*temp)
 
 def _delete(self,attribute: int,val: str):
  '''
  删除学生节点
  attribute: 需要根据哪个属性删除,1.id 或 2.name
  '''
  if attribute == 1:
   self.student.delete(val)
  elif attribute == 2:
   self.student.delete_name(val)
 
 def _insert(self,idx,*temp):
  '''
  把学生节点插入到指定的位置
  '''
  self.student.insert(idx,*temp)
 
 def _search(self,attribute,val):
  '''
  查询
  '''
  if attribute == 1:
   return self.student.search_id(val)
  elif attribute == 2:
   return self.student.search_name(val)
 
 def _modity(self,attribute,id_,*temp):
  '''
  修改
  '''
  if attribute == 1:
   self.student.modity_id(id_,*temp)
  elif attribute == 2:
   print('[info]:因为没实现,所以什么也不做')
   pass #根据name修改没有写
 
 
 
 
class Cmd_UI(UI):
 '''
 命令行的交互界面
 '''
 def __init__(self):
  super(Cmd_UI,self).__init__()
 
 def get_input_1_2(self,info: str):
  '''
  获得输入,返回1或者2
  info: 描述输入的信息
  '''
  x = None
  while x == None:
   temp = input(info)
   if temp == '1':
    x = 1
   elif temp == '2':
    x = 2
   else:
    print('你只能输入1或者2')
  return x
 
 def get_input_arg(self):
  '''
  获得用户的输入构造学生节点
  '''
  id_ = input('请输入id')
  name = input('请输入姓名')
  sex = input('请输入性别')
  age = input('请输入年龄')
  score = input('请输入成绩')
  return (id_,name,sex,age,score)
 
 def delete(self):
  '''
  删除节点
  '''
  info = '你想要根据哪个属性删除节点:1.id 2.name'
  attribute = self.get_input_1_2(info)
  val = input('输入你想要删除的值:')
  self._delete(attribute,val)
 
 def show(self):
  '''
  显示
  '''
  rel = self._show()
  for i in rel:
   print(i)
 
 def add(self):
  '''
  增加学生结点
  '''
  info = '你想要插入的位置:1.左边 2.右边'
  direction = self.get_input_1_2(info)
  arg = self.get_input_arg()
  self._add(direction,*arg)
 
 def insert(self):
  '''
  新学生,插入到指定的位置
  '''
  idx = int(input('输入要插入的位置'))
  temp = self.get_input_arg()
  self._insert(idx,*temp)
 
 def search(self):
  '''
  查询学生
  '''
  info = '你想要根据哪个属性搜索节点:1.id 2.name'
  attribute = self.get_input_1_2(info)
  val = input('输入你想要查询的值:')
 
  print(self._search(attribute,val))
 
 def modity(self):
  '''
  修改学生信息
  '''
  info = '你想要根据哪个属性搜索节点:1.id 2.name'
  attribute = self.get_input_1_2(info)
  val_ = input('输入要查询的值:')
  temp = self.get_input_arg()
  self._modity(attribute,val_,*temp)
 
 def main(self):
  '''
  主流程
  '''
  info = '''
  *******************
  *kalpa学生管理系统*
  * 0.显示数据 *
  * 1.增加数据 *
  * 2.删除数据 *
  * 3.查询数据 *
  * 4.修改数据 *
  * 5.保存并退出 *
  *******************
  '''
  print(info)
  a = '0'
  while a in ['0','1','2','3','4','5']:
   if a == '0':
    self.show()
   elif a == '1':
    self.add()
   elif a == '2':
    self.delete()
   elif a == '3':
    self.search()
   elif a == '4':
    self.modity()
   elif a == '5':
    self.quit()
    return
   a = input('>>')
 
 
if __name__ == "__main__":
 ui = Cmd_UI()
 ui.main()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_41600708/article/details/107445207