【问题描述】
项目六定义了ClassManager类用于管理班级信息,请扩展该类使之能将班级信息保存到“学生信息.json”中,并能从这个文件读取班级信息。学生信息如下所示:
输出结果:
{"clsname":"2019级计算机1班","teacher":"王老师","students":[{"sno":"0001","name":"张三","sex":"男","clsname":"2019级计算机1班"},{"sno":"0002","name":"李四","sex":"男","clsname":"2019级计算机1班"},{"sno":"0003","name":"王月","sex":"女","clsname":"2019级计算机1班"}]}
备注:以上是文件“学生信息.json”中的内容。
【题前思考】
根据问题描述,填写表7-2-1。
表7-2-1 问题分析
【解题思路】
本活动的源程序包含3个方面的内容:
一是导入模块文件。程序需要os、json及调用学生管理类中的班级管理模块ClassManager,因此需要导入这3个模块的内容。
二是定义一个类ClassManager_json,通过继承ClassManager类来扩展它读写班级信息的功能。计算机中的数据先是存放在内存中,即将班级名称、教师、学生信息存放在内存中,只有通过保存在文件中,数据才能真正保存下来。因此接下来需要使用类方法将班级名称、教师、学生信息保存到json文件中。
三是通过调用类对象,使用json模块读写文件中的数据。
【程序代码】
【代码分析】
①:导入json模块读写json格式的文件。json(javascript object notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
②:从a6_1_2班级管理类模块中导入ClassManager类。ClassManager类是项目六定义的,它在a6_1_2班级管理类模块中。
③:以ClassManager为父类,定义一个子类ClassManager_json,子类继承父类的方法、属性,同时在子类扩展新的方法和属性。
④:初始化父类的对象。
⑤:对self.pupils中的每一个项s执行循环体。self.pupils是Student类对象的列表,所以变量s是Student类对象,语句res.append({'sno':s.sno,'name':s.name,'sex':s.sex,'clsname':s.clsname})是将学生信息以字典的形式加入列表res中。json要求数据必须为列表或字典,所以将学生信息转换为字典列表。
⑥:以写(write)的方式打开文件命名为f,执行完with语句内部的语句块后无论发生异常与否都会自动关闭文件。
⑦:json.dump( )将第一个参数表示的内容(班级名称、教师、学生信息)写入到第二个参数表示的文件f中,ensure_ascii=False表示直接写入汉字,ensure_ascii=True会将所有非ASCII 字符转义,写到文件中的是汉字的代码。
⑧:@classmethod表示类方法,可以用类名直接调用。
⑨:定义函数load_json( )从path表示的json文件中读取班级信息,创建ClassManager_json对象,即从json文件中还原出班级管理对象。
⑩:以读(read)的方式打开文件命名为f,并在with语句内的语句块执行完后关闭文件。res=json.load( )将文件内容以字典或字典列表的形式读入并赋给变量res。
:用从json文件中读入的班级名称(clsname)和教师姓名(teacher)创建一个ClassManager_json对象,赋给变量students。函数将会返回班级管理对象ClassManager_json类对象students给调用者。
:对res['students']中的每一个项r执行循环体。res['students']是学生字典构成的列表,所以r是学生信息的字典,包括学生的学号sno、姓名name、性别sex等信息,调用students.add( )方法,将这些学生添加到班级中。
:创建班级。
:添加学生。
:将班级保存到json文件。
:把json文件中的信息读取出来还原成班级对象cls2。
:调用cls2.show( )方法显示班级信息,可以看出cls2中的信息与原始信息相同。
【技术全貌】
json是Python中的互联网数据处理模块,它将Python数据编码成对应的文档。表7-2-2中列出了json模块中的dumps、dump、loads、load4个函数。在读写文件的操作中,不可避免要打开或关闭文件,表7-2-3列出了文件的部分操作方法。
表7-2-2 json模块中的函数
续表
表7-2-3 文件的操作方法