0基础跟德姆(dom)一起学AI Python进阶03-面向对象版: 学生管理系统

* 面向对象版: 学生管理系统
  * Student学生类
  * StudentCMS学生管理类
  * main.py 程序的主入口
  * 加入文件: student.txt存储学生信息
* 深拷贝和浅拷贝
  * 可变类型
  * 不可变类型

---

1.学生管理系统-分析

* 涉及到的知识点

  * 面向对象
  * 列表, 字典
  * for, if, input...
  * 文件操作
  * ......

* 需求分析

* 结论: 分模块(.py文件)进行开发

  * **main.py**    程序的主入口

  * **student.py**   存储学生类(Student类)的信息

    > 学生的属性: **姓名, 年龄, 性别, 手机号, 备注**

  * **studentcms.py** 存储学生管理类(StudentCms类)的信息

    > CMS全称: Content Management System, 内容管理系统
    >
    > 具体的**操作学生信息, 例如: 增删改查, 保存, 退出系统等**都是在这里完成的.

2.学生类代码实现

* 如下的代码是在  **student.py** 文件中写的

  ```python
  
  # 定义学生类, 属性为: 姓名, 年龄, 性别, 联系方式, 描述信息.
  class Student(object):
      # 1. 在__init__()魔法方法中, 完成 对象属性(实例属性) 的初始化.
      def __init__(self, name, age, gender, mobile, des):
          """
          完成对象属性的初始化
          :param name: 姓名
          :param age: 年龄
          :param gender: 性别
          :param mobile: 手机号
          :param des: 描述信息(备注)
          """
          self.name = name
          self.age = age
          self.gender = gender
          self.mobile = mobile
          self.des = des
  
      # 2. 重写__str__魔法方法, 打印(学生)对象的各个属性值.
      def __str__(self):
          return f'姓名: {self.name}, 年龄: {self.age}, 性别: {self.gender}, 手机号: {self.mobile}, 备注: {self.des}'
  
  
  # 3. 在main函数中测试学生类的内容, 加main函数的目的: 防止如下的测试代码在 调用者中被执行.
  if __name__ == '__main__':
      s = Student('乔峰', 33, '男', '13112345678', '丐帮帮主')
      print(s)
  ```


3.学生管理类-初始化及打印界面

* 如下的代码是在  **studentcms.py** 文件中写的

  ```python
  # 导包
  
  
  # 自定义的学生管理类, 负责完成对学生信息的管理操作, 例如: 增删改查, 保存等...
  class StudentCms(object):
      # 1. 重构 __init__()函数, 初始化info变量, 它是列表嵌套字典的形式, 存储学生信息.
      def __init__(self):
          self.info = []      # 对象属性(实例属性, 对象变量, 实例变量)
  
      # 2. 定义函数show_view(), 用于打印提示界面
      def show_view(self):
          print('*' * 31)
          print('欢迎来到黑马学生管理系统V2.0')
          print('\t1.添加学生信息')
          print('\t2.删除学生信息')
          print('\t3.修改学生信息')
          print('\t4.查询单个学生信息')
          print('\t5.显示所有学生信息')
          print('\t6.保存学生信息')
          print('\t0.退出系统')
          print('*' * 31)
  
  ```
4.学生管理类-基本框架搭建

* 如下的代码是在  **studentcms.py** 文件中写的

  ```python
  # 导包
  import time
  
  # 自定义的学生管理类, 负责完成对学生信息的管理操作, 例如: 增删改查, 保存等...
  class StudentCms(object):
      # 1. 重构 __init__()函数, 初始化info变量, 它是列表嵌套字典的形式, 存储学生信息.
      def __init__(self):
          self.info = []      # 对象属性(实例属性, 对象变量, 实例变量)
  
      # 2. 定义函数show_view(), 用于打印提示界面
      def show_view(self):
          print('*' * 31)
          print('欢迎来到黑马学生管理系统V2.0')
          print('\t1.添加学生信息')
          print('\t2.删除学生信息')
          print('\t3.修改学生信息')
          print('\t4.查询单个学生信息')
          print('\t5.显示所有学生信息')
          print('\t6.保存学生信息')
          print('\t0.退出系统')
          print('*' * 31)
  
      # 3. 定义函数add_student, 负责: 添加学生信息
      def add_student(self):
          pass
  
      # 4. 定义函数del_student, 负责: 删除学生信息
      def del_student(self):
          pass
  
      # 5. 定义函数update_student, 负责: 修改学生信息
      def update_student(self):
          pass
  
      # 6. 定义函数search_student, 负责: 查询单个学生信息
      def search_student(self):
          pass
  
      # 7. 定义函数show_all_student, 负责: 显示所有学生信息
      def show_all_student(self):
          pass
  
      # 8. 定义函数save_student, 负责: 保存学生信息到文件
      def save_student(self):
          pass
  
      # 9. 定义函数load_student(), 负责: 从文件中加载学生信息到 self.info 列表中.
      def load_student(self):
          pass
  
      # 10. 定义函数start(), 表示具体的业务逻辑, 即: 用户录入编号, 进行对应的操作.
      def start(self):
          # 10.1
  
          # 10.2 循环提示用户录入操作的编号, 然后进行对应的操作.
          while True:
              # 10.3 为了让效果更好, 更真实, 我们加入: 休眠功能.
              time.sleep(1)
              # 10.4 打印提示界面
              self.show_view()
              # 10.5 提示用户录入要操作的编号, 并接收.
              num = input('请录入要操作的编号: ')
              # 10.6 根据用户录入的编号, 进行对应的操作.
              if num == '1':
                  print('添加学生\n')
                  self.add_student()
              elif num == '2':
                  print('删除学生\n')
                  self.del_student()
              elif num == '3':
                  print('修改学生\n')
                  self.update_student()
              elif num == '4':
                  print('查询单个学生\n')
                  self.search_student()
              elif num == '5':
                  print('显示所有学生\n')
                  self.show_all_student()
              elif num == '6':
                  print('保存学生信息\n')
                  self.save_student()
              elif num == '0':
                  # 细节: 增加二次退出判断.
                  s = input('请确认要退出吗(Y/N): ')
                  if s.lower() == 'y':        # 字符串的lower()函数, 目的是: 把字母转成小写形式.
                      print('谢谢您的使用, 我们下次再会!')
                      break
              else:
                  print('录入有误, 请重新录入!\n')
  
  
  # 11. 测试学生管理类的代码.
  if __name__ == '__main__':
      stu_cms = StudentCms()
      stu_cms.start()
  ```
5.程序主入口-编写

* 如下的代码是在  **main.py** 文件中写的

  ```python
  # 导包
  from student_cms import StudentCms
  
  # main函数, 作为程序的主入口, 即: 整个学生管理系统的代码是从这里开始执行的.
  if __name__ == '__main__':
      # 1. 创建学生管理类对象.
      stu_cms = StudentCms()
      # 2. 调用start()函数, 启动: 学生管理系统.
      stu_cms.start()
  ```

6.增删改查学生信息-代码实现

* 添加学生信息

  ```python
  # 3. 定义函数add_student, 负责: 添加学生信息
  def add_student(self):
      # 3.1 提示用户录入要添加的学生信息.
      name = input('请录入要添加的学生姓名: ')
      age = int(input('请录入要添加的学生年龄: '))
      gender = input('请录入要添加的学生性别(男/女): ')
      mobile = input('请录入要添加的学生手机号: ')
      des = input('请录入要添加的学生备注: ')
      # 3.2 把上述的学生信息, 封装成: 学生对象.
      stu = Student(name, age, gender, mobile, des)
      # 3.3 把上述的学生对象, 添加到 self.info 列表中.
      self.info.append(stu)
      # 3.4 提示即可.
      print('添加学员信息成功!\n')
  ```

* 查看所有学生信息

  ```python

# 7. 定义函数show_all_student, 负责: 显示所有学生信息
  def show_all_student(self):
      # 7.1 判断是否有学生信息, 有: 则遍历输出.
      if len(self.info) > 0:
          for stu in self.info:
              print(stu)
          print() # 加个换行, 代码效果更好.
      else:
          # 7.2 无, 则提示: 先添加, 后查询.
          print('暂无学生信息, 请添加后查询!\n')
  ```

* 删除学生信息

  ```python
  # 4. 定义函数del_student, 负责: 删除学生信息
  def del_student(self):
      # 4.1 请录入要删除的学员的姓名.
      del_name = input('请录入要删除的学员的姓名: ')
      # 4.2 遍历info列表, 看是否有该学员.
      for stu in self.info:
          if stu.name == del_name:
              # 4.3 如果有同名学员, 就删除该学生.
              self.info.remove(stu)
              print(f'删除 {del_name} 学生信息成功!\n')
              # 4.4 核心细节, 记得: break
              break
      else:
          # 4.5 走这里, 没找到, 提示即可.
          print('查无此人, 请校验后再删除!\n')
  ```

* 修改学生信息

  ```python
  # 5. 定义函数update_student, 负责: 修改学生信息
  def update_student(self):
      # 5.1 请录入要修改的学员的姓名.
      update_name = input('请录入要修改的学员的姓名: ')
      # 5.2 遍历info列表, 看是否有该学员.
      for stu in self.info:
          if stu.name == update_name:
              # 4.3 如果有同名学员, 就修改该学生信息.
              stu.age = int(input('请录入要添加的学生年龄: '))
              stu.gender = input('请录入要添加的学生性别(男/女): ')
              stu.mobile = input('请录入要添加的学生手机号: ')
              stu.des = input('请录入要添加的学生备注: ')
  
              print(f'修改 {update_name} 学生信息成功!\n')
              # 4.4 核心细节, 记得: break
              break
      else:
          # 4.5 走这里, 没找到, 提示即可.
          print('查无此人, 请校验后再修改!\n')
  ```

* 查询单个学生信息

  ```python
  # 6. 定义函数search_student, 负责: 查询单个学生信息
  def search_student(self):
      # 6.1 请录入要查询的学员的姓名.
      search_name = input('请录入要查询的学员的姓名: ')
      # 6.2 遍历info列表, 看是否有该学员.
      for stu in self.info:
          if stu.name == search_name:
              # 6.3 如果有同名学员, 就打印该学生.
              print(stu, end='\n\n')
              # 6.4 核心细节, 记得: break
              break
      else:
          # 6.5 走这里, 没找到, 提示即可.
          print('查无此人, 请校验后再查询!\n')
  ```

7.扩展-dict属性

```python
"""
__dict__ 属性介绍:
    作用:
        1. 它是每个类的内置属性, 类似于 魔法方法一样, 每个类都有, 可以直接拿来使用.
        2. 它可以把对象变成字典形式, 即: {属性名:属性值, 属性名:属性值}
"""
from student import Student

# 1. 创建学生类对象.
s1 = Student('乔峰', 33, '男', '111', '帮主')
s2 = Student('虚竹', 29, '男', '222', '和尚')
s3 = Student('段誉', 23, '男', '333', '渣男')


# 2. 需求1: 把s1对象, 封装成 字典形式.
# 方式1: 手动配置
dict1 = {'name': s1.name, 'age': s1.age, 'gender': s1.gender, 'mobile': s1.mobile, 'des': s1.des}
print(dict1)

# 方式2: 通过类内置的 __dict__属性实现.
dict2 = s1.__dict__
print(dict2)
print('-' * 31)

# 3. 需求2: 把s1, s2, s3对象添加到列表中, 形成: 列表嵌套字典的形式, 存储学生数据.
# 即: [学生对象, 学生对象, 学生对象]  =>  [{学生信息}, {学生信息}, {学生信息}]
# 3.1 定义列表, 记录 学生对象.
info = [s1, s2, s3]
# print(info)   # [<student.Student object at 0x000001E84547E5E0>, <student.Student object at 0x000001E84547E520>, <student.Student object at 0x000001E84547E2B0>]

# 3.2 把上述的学生列表, 转成 列表嵌套字典形式.
# 方式1: 完整版.
list_data = []
for stu in info:
    list_data.append(stu.__dict__)
print(list_data) # [{'name': '乔峰', 'age': 33, 'gender': '男', 'mobile': '111', 'des': '帮主'}, {...}, {...}]

# 方式2: 列表推导式版
list_data2 = [stu.__dict__ for stu in info]
print(list_data2)
```

8.保存学生信息

```python
# 8. 定义函数save_student, 负责: 保存学生信息到文件
def save_student(self):
    # 8.1 获取文件对象, 往 student.data 文件中, 添加学生数据.
    with open('./student.data', 'w', encoding='utf-8') as my_f:
        # 8.2 把self.info列表, 从 [学生对象, 学生对象...]  =>  "[{学生信息}, {学生信息}, ...]"
        list_data = str([stu.__dict__ for stu in self.info])
        # print(f'list_data: {list_data}')
        # print(type(list_data))      # <class 'str'>
        # 8.3 把上述的 字符串形式的 列表嵌套字典(即: 所有学生的数据), 写到目的地文件中.
        my_f.write(list_data)
        # 8.4 提示即可.
        print('保存学生信息成功!\n')
```

9.加载学生信息

```python
# 9. 定义函数load_student(), 负责: 从文件中加载学生信息到 self.info 列表中.
def load_student(self):
    # 9.1 创建文件对象, 负责从 student.data文件中 读取数据.
    try:
        with open('./student.data', 'r', encoding='utf-8') as my_f:
            # 9.2 一次性从文件中读取所有的数据.
            data = my_f.read()      # data的格式: "[{学生信息}, {学生信息}, {学生信息}]"
            # 9.3 对读取到的数据做判断, 如果文件为空, 则给data赋一个默认值.
            if len(data) <= 0:
                data = "[]"
            # 9.4 把上述的data转成 列表
            list_data = eval(data)    # 相当于把两端的引号去掉, 是啥就是转成啥.  [{学生信息}, {学生信息}, {学生信息}]
            # 9.5 列表推导式方式实现, 把上述的list_data(列表嵌套字典)数据, 封装成学生对象, 然后添加到self.info列表中.
            # self.info = [Student('乔峰', 33, '男', '111', '帮主') for stu_dict in list_data]
            self.info = [
                Student(stu_dict['name'], stu_dict['age'], stu_dict['gender'], stu_dict['mobile'], stu_dict['des'])
                         for stu_dict in list_data
            ]
    except:
        # 9.6 走这里, 说明程序出问题了, 原因是: 存储学生信息的 student.data文件不存在.
        my_f = open('./student.data', 'w', encoding='utf-8')    # 写的操作, 目的地文件不存在, 会自动创建.
        my_f.close()
```

10.什么情况下用静态方法

* 改造 **studentcms.py**文件中的 show_view()函数为: 静态方法

  ```python
  # 2. 定义函数show_view(), 用于打印提示界面. 因为该函数不涉及self和cls, 所以定义为: 静态方法.
  @staticmethod
  def show_view():
      print('*' * 31)
      print('欢迎来到黑马学生管理系统V2.0')
      print('\t1.添加学生信息')
      print('\t2.删除学生信息')
      print('\t3.修改学生信息')
      print('\t4.查询单个学生信息')
      print('\t5.显示所有学生信息')
      print('\t6.保存学生信息')
      print('\t0.退出系统')
      print('*' * 31)
  ```

* 同理, 修改下调用的代码, **具体是 10.4 步骤的代码**

  ```python
  # 10. 定义函数start(), 表示具体的业务逻辑, 即: 用户录入编号, 进行对应的操作.
  def start(self):
      # 10.1 调用load_student()函数, 加载学生数据.
      self.load_student()
  
      # 10.2 循环提示用户录入操作的编号, 然后进行对应的操作.
      while True:
          # 10.3 为了让效果更好, 更真实, 我们加入: 休眠功能.
          time.sleep(1)
          # 10.4 打印提示界面
          StudentCms.show_view()  # 静态方法调用方式1: 类名. 的方式.  推荐.
          # self.show_view()      # 静态方法调用方式2: 对象名.的方式  虽然支持, 但是: 不推荐.
  
          # 10.5 提示用户录入要操作的编号, 并接收.
          num = input('请录入要操作的编号: ')
          # 10.6 根据用户录入的编号, 进行对应的操作.
          if num == '1':
              # print('添加学生\n')
              self.add_student()
          elif num == '2':
              # print('删除学生\n')
              self.del_student()
          elif num == '3':
              # print('修改学生\n')
              self.update_student()
          elif num == '4':
              # print('查询单个学生\n')
              self.search_student()
          elif num == '5':
              # print('显示所有学生\n')
              self.show_all_student()
          elif num == '6':
              # print('保存学生信息\n')
              self.save_student()
          elif num == '0':
              # 细节: 增加二次退出判断.
              s = input('请确认要退出吗(Y/N): ')
              if s.lower() == 'y':  # 字符串的lower()函数, 目的是: 把字母转成小写形式.
                  print('谢谢您的使用, 我们下次再会!')
                  break
          else:
              print('录入有误, 请重新录入!\n')
  
  ```

11.完整版的学生管理系统

* **student.py** 文件中的代码

  ```python
  # 定义学生类, 属性为: 姓名, 年龄, 性别, 联系方式, 描述信息.
  class Student(object):
      # 1. 在__init__()魔法方法中, 完成 对象属性(实例属性) 的初始化.
      def __init__(self, name, age, gender, mobile, des):
          """
          完成对象属性的初始化
          :param name: 姓名
          :param age: 年龄
          :param gender: 性别
          :param mobile: 手机号
          :param des: 描述信息(备注)
          """
          self.name = name
          self.age = age
          self.gender = gender
          self.mobile = mobile
          self.des = des
  
      # 2. 重写__str__魔法方法, 打印(学生)对象的各个属性值.
      def __str__(self):
          return f'姓名: {self.name}, 年龄: {self.age}, 性别: {self.gender}, 手机号: {self.mobile}, 备注: {self.des}'
  
  
  # 3. 在main函数中测试学生类的内容, 加main函数的目的: 防止如下的测试代码在 调用者中被执行.
  if __name__ == '__main__':
      s = Student('乔峰', 33, '男', '13112345678', '丐帮帮主')
      print(s)
  ```

* **studentcms.py** 文件中的代码

  ```python
  # 导包
  import time
  
  from student import Student
  
  
  # 自定义的学生管理类, 负责完成对学生信息的管理操作, 例如: 增删改查, 保存等...
  class StudentCms(object):
      # 1. 重构 __init__()函数, 初始化info变量, 它是列表嵌套字典的形式, 存储学生信息.
      def __init__(self):
          # info格式, 例如: [<student.Student object at 0x000001FDD1479670>, <student.Student object at 0x000001FDD1B961C0>]
          self.info = []  # 对象属性(实例属性, 对象变量, 实例变量)
  
      # 2. 定义函数show_view(), 用于打印提示界面. 因为该函数不涉及self和cls, 所以定义为: 静态方法.
      @staticmethod
      def show_view():
          print('*' * 31)
          print('欢迎来到黑马学生管理系统V2.0')
          print('\t1.添加学生信息')
          print('\t2.删除学生信息')
          print('\t3.修改学生信息')
          print('\t4.查询单个学生信息')
          print('\t5.显示所有学生信息')
          print('\t6.保存学生信息')
          print('\t0.退出系统')
          print('*' * 31)
  
      # 3. 定义函数add_student, 负责: 添加学生信息
      def add_student(self):
          # 3.1 提示用户录入要添加的学生信息.
          name = input('请录入要添加的学生姓名: ')
          age = int(input('请录入要添加的学生年龄: '))
          gender = input('请录入要添加的学生性别(男/女): ')
          mobile = input('请录入要添加的学生手机号: ')
          des = input('请录入要添加的学生备注: ')
          # 3.2 把上述的学生信息, 封装成: 学生对象.
          stu = Student(name, age, gender, mobile, des)
          # 3.3 把上述的学生对象, 添加到 self.info 列表中.
          self.info.append(stu)
          # 3.4 提示即可.
          print('添加学员信息成功!\n')
  
      # 4. 定义函数del_student, 负责: 删除学生信息
      def del_student(self):
          # 4.1 请录入要删除的学员的姓名.
          del_name = input('请录入要删除的学员的姓名: ')
          # 4.2 遍历info列表, 看是否有该学员.
          for stu in self.info:
              if stu.name == del_name:
                  # 4.3 如果有同名学员, 就删除该学生.
                  self.info.remove(stu)
                  print(f'删除 {del_name} 学生信息成功!\n')
                  # 4.4 核心细节, 记得: break
                  break
          else:
              # 4.5 走这里, 没找到, 提示即可.
              print('查无此人, 请校验后再删除!\n')
  
  
      # 5. 定义函数update_student, 负责: 修改学生信息
      def update_student(self):
          # 5.1 请录入要修改的学员的姓名.
          update_name = input('请录入要修改的学员的姓名: ')
          # 5.2 遍历info列表, 看是否有该学员.
          for stu in self.info:
              if stu.name == update_name:
                  # 4.3 如果有同名学员, 就修改该学生信息.
                  stu.age = int(input('请录入要添加的学生年龄: '))
                  stu.gender = input('请录入要添加的学生性别(男/女): ')
                  stu.mobile = input('请录入要添加的学生手机号: ')
                  stu.des = input('请录入要添加的学生备注: ')
  
                  print(f'修改 {update_name} 学生信息成功!\n')
                  # 4.4 核心细节, 记得: break
                  break
          else:
              # 4.5 走这里, 没找到, 提示即可.
              print('查无此人, 请校验后再修改!\n')
  
      # 6. 定义函数search_student, 负责: 查询单个学生信息
      def search_student(self):
          # 6.1 请录入要查询的学员的姓名.
          search_name = input('请录入要查询的学员的姓名: ')
          # 6.2 遍历info列表, 看是否有该学员.
          for stu in self.info:
              if stu.name == search_name:
                  # 6.3 如果有同名学员, 就打印该学生.
                  print(stu, end='\n\n')
                  # 6.4 核心细节, 记得: break
                  break
          else:
              # 6.5 走这里, 没找到, 提示即可.
              print('查无此人, 请校验后再查询!\n')
  
      # 7. 定义函数show_all_student, 负责: 显示所有学生信息
      def show_all_student(self):
          # 7.1 判断是否有学生信息, 有: 则遍历输出.
          if len(self.info) > 0:
              for stu in self.info:
                  print(stu)
              print() # 加个换行, 代码效果更好.
          else:
              # 7.2 无, 则提示: 先添加, 后查询.
              print('暂无学生信息, 请添加后查询!\n')
  
  
      # 8. 定义函数save_student, 负责: 保存学生信息到文件
      def save_student(self):
          # 8.1 获取文件对象, 往 student.data 文件中, 添加学生数据.
          with open('./student.data', 'w', encoding='utf-8') as my_f:
              # 8.2 把self.info列表, 从 [学生对象, 学生对象, 学生对象]  =>  "[{学生信息}, {学生信息}, {学生信息}]"
              list_data = str([stu.__dict__ for stu in self.info])
              # print(f'list_data: {list_data}')
              # print(type(list_data))      # <class 'str'>
              # 8.3 把上述的 字符串形式的 列表嵌套字典(即: 所有学生的数据), 写到目的地文件中.
              my_f.write(list_data)
              # 8.4 提示即可.
              print('保存学生信息成功!\n')
  
  
      # 9. 定义函数load_student(), 负责: 从文件中加载学生信息到 self.info 列表中.
      def load_student(self):
          # 9.1 创建文件对象, 负责从 student.data文件中 读取数据.
          try:
              with open('./student.data', 'r', encoding='utf-8') as my_f:
                  """
                  数据变化流程如下:
                      data的数据格式:
                          "[{'name': '张三', 'age': 23, 'gender': '男', 'mobile': '111', 'des': '程序员'}, {学生信息}...]"
                     如果 student.data文件为空, 则: data的数据格式为: 
                          "[]"
                     list_data的数据格式:
                          [{'name': '张三', 'age': 23, 'gender': '男', 'mobile': '111', 'des': '程序员'}, {学生信息}...]
                     for stu_dict in list_data:
                          遍历list_data列表, 获取到每个元素(即: 字典形式的数据), 然后赋值给变量 stu_dict
                     stu_dict的数据格式:
                          {'name': '张三', 'age': 23, 'gender': '男', 'mobile': '111', 'des': '程序员'}
                         回顾:
                              问题: 如何获取字典的值呢? 
                              答案: 字典名['键名']  或者  字典名.get('键名')
                         例如:
                              stu_dict['name']        张三
                              stu_dict['age']         23
                              stu_dict['gender']      男
                              stu_dict['mobile']      111
                              stu_dict['des']         程序员
                     把上述的数据封装成学生对象, 即:
                          Student('张三', 23, '男', '111', '程序员')
                          Student(stu_dict['name'], stu_dict['age'], stu_dict['gender'], stu_dict['mobile'], stu_dict['des'])
                     大白话总结:
                          self.info = 列表推导式[ Student(字典形式的学生数据-获取每组值) for 字典形式的学生数据 in 列表嵌套字典形式的学生数据]
                  """
                  # 9.2 一次性从文件中读取所有的数据.
                  data = my_f.read()      # data的格式: "[{学生信息}, {学生信息}, {学生信息}]"
                  # 9.3 对读取到的数据做判断, 如果文件为空, 则给data赋一个默认值.
                  if len(data) <= 0:
                      data = "[]"
                  # 9.4 把上述的data转成 列表
                  list_data = eval(data)    # 相当于把两端的引号去掉, 是啥就是转成啥.  [{学生信息}, {学生信息}, {学生信息}]
                  # 9.5 列表推导式方式实现, 把上述的list_data(列表嵌套字典)数据, 封装成学生对象, 然后添加到self.info列表中.
                  # self.info = [Student('乔峰', 33, '男', '111', '帮主') for stu_dict in list_data]
                  self.info = [
                      Student(stu_dict['name'], stu_dict['age'], stu_dict['gender'], stu_dict['mobile'], stu_dict['des'])
                               for stu_dict in list_data
                  ]
          except:
              # 9.6 走这里, 说明程序出问题了, 原因是: 存储学生信息的 student.data文件不存在.
              my_f = open('./student.data', 'w', encoding='utf-8')    # 写的操作, 目的地文件不存在, 会自动创建.
              my_f.close()
  
      # 10. 定义函数start(), 表示具体的业务逻辑, 即: 用户录入编号, 进行对应的操作.
      def start(self):
          # 10.1 调用load_student()函数, 加载学生数据.
          self.load_student()
  
          # 为了让测试效果更明显, 我们先给几个测试数据. 项目正式上线的时候, 注释掉或者删除掉即可.
          # s1 = Student('乔峰', 33, '男', '111', '帮主')
          # s2 = Student('虚竹', 29, '男', '222', '和尚')
          # s3 = Student('段誉', 23, '男', '333', '渣男')
          # self.info.append(s1)
          # self.info.append(s2)
          # self.info.append(s3)
  
          # 10.2 循环提示用户录入操作的编号, 然后进行对应的操作.
          while True:
              # 10.3 为了让效果更好, 更真实, 我们加入: 休眠功能.
              time.sleep(1)
              # 10.4 打印提示界面
              StudentCms.show_view()  # 静态方法调用方式1: 类名. 的方式.  推荐.
              # self.show_view()      # 静态方法调用方式2: 对象名.的方式  虽然支持, 但是: 不推荐.
  
              # 10.5 提示用户录入要操作的编号, 并接收.
              num = input('请录入要操作的编号: ')
              # 10.6 根据用户录入的编号, 进行对应的操作.
              if num == '1':
                  # print('添加学生\n')
                  self.add_student()
              elif num == '2':
                  # print('删除学生\n')
                  self.del_student()
              elif num == '3':
                  # print('修改学生\n')
                  self.update_student()
              elif num == '4':
                  # print('查询单个学生\n')
                  self.search_student()
              elif num == '5':
                  # print('显示所有学生\n')
                  self.show_all_student()
              elif num == '6':
                  # print('保存学生信息\n')
                  self.save_student()
              elif num == '0':
                  # 细节: 增加二次退出判断.
                  s = input('请确认要退出吗(Y/N): ')
                  if s.lower() == 'y':  # 字符串的lower()函数, 目的是: 把字母转成小写形式.
                      print('谢谢您的使用, 我们下次再会!')
                      break
              else:
                  print('录入有误, 请重新录入!\n')
  
  
  # 11. 测试学生管理类的代码.
  if __name__ == '__main__':
      stu_cms = StudentCms()
      stu_cms.start()
  ```

* **main.py** 文件中的代码

  ```python
  # 导包
  from student_cms import StudentCms
  
  # main函数, 作为程序的主入口, 即: 整个学生管理系统的代码是从这里开始执行的.
  if __name__ == '__main__':
      # 1. 创建学生管理类对象.
      stu_cms = StudentCms()
      # 2. 调用start()函数, 启动: 学生管理系统.
      stu_cms.start()
  ```

* **student.data** 文件中的数据格式为:

  ```python
  [{'name': '张三', 'age': 23, 'gender': '男', 'mobile': '111', 'des': '程序员'},{}...]
  ```
 

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值