JSON 和 pickle
序列化:把数据对象变成字符串的形式,这样可以保存在文件中。反之就是反序列化
python自带的str()可以完成序列化,然后eval()可以反序列化,但是我们先把他们忘记。不知道适用范围是多大。
我们用json的规范来做序列化和反序列化。
import json dica = {‘name‘:‘Alice‘, ‘age‘:18, ‘from‘:‘ShangHai‘ } stra = json.dumps(dica) # 序列化 print(type(stra),stra) dica2 = json.loads(stra) # 反序列化 print(type(dica2),dica2) strb = ‘{"name":"Jack","age":22,"from":"BeiJing"}‘ # JSON只认双引号,所以字符串内部要双引号 print(type(strb),strb) dicb = json.loads(strb) # 反序列化 print(type(dicb),dicb)
一种需求是序列化成字符串之后存入文件保存起来。下次要用的时候再读取文件,反序列化生成之前的数据。对于这种情况,对应有两个便捷的方法可以直接完成。
import json dica = {‘name‘:‘Alice‘, ‘age‘:18, ‘from‘:‘ShangHai‘ } with open("testjson.txt",‘w‘,encoding=‘utf-8‘) as file: json.dump(dica,file)
可以去查看一下,运行目录下是否生成了一个文件。然后再来反序列化
import json with open("testjson.txt",‘r‘,encoding=‘utf-8‘) as file: data = json.load(file) print(type(data),data)
上面的JSON的序列化并不支持python所有的数据类型。但是JSON是通用的规范,也就是JSON序列化之后的数据到其他语言环境也能识别。
对于不支持的数据类型,应该可以加一步编解码,但是如果别的语言环境也不支持这个数据类型,那么即使能序列化也没有用。
不过python序列化保存之后再给python反序列化使用,就没有数据类型的问题,那么可以使用pickle。
python的pickle模块实现了python的所有数据序列和反序列化。基本上功能使用和JSON模块没有太大区别,方法也同样是dumps/dump和loads/load
import pickle dica = {‘name‘:‘Alice‘, ‘age‘:18, ‘from‘:‘ShangHai‘ } stra = pickle.dumps(dica) # 序列化 print(type(stra),stra) # 这里bytes类型了,只有二进制类型才有可能把所有的数据类型都序列化 dica2 = pickle.loads(stra) # 反序列化 print(type(dica2),dica2)
软件目录开发规范
假设项目名称是Foo,项目名称的首字母大写。下面是一个简单的目录结构:
Foo/
|-- bin/
| |-- foo
|
|-- foo/
| |-- tests/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- docs/
| |-- conf.py
| |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README
- bin/: 存放项目的一些可执行文件,当然你可以起名
script/
之类的也行。 foo/
: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/
存放单元测试代码; (3) 程序的入口最好命名为main.py
。docs/
: 存放一些文档。setup.py
: 安装、部署、打包的脚本。requirements.txt
: 存放软件依赖的外部Python包列表。README
: 项目说明文件。
不同目录间进行模块调用
python里一个文件夹下如果有一个__init__.py的空文件,这就不是一个普通的文件夹了,这是一个包。
要调用包里的模块,可以使用:from 包名 import 模块名
要能够调用,还要先保证包的上级目录在环境变量里。要动态的获取到程序的目录和上级目录,并且导入环境变量,看下面的例子:
import os,sys print(__file__) # 打印相对路径 print(os.path.abspath(__file__)) # 打印绝对路径 print(os.path.dirname(os.path.abspath(__file__))) # 打印上一级目录,这里是去掉了文件名 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 打印再上一级目录 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 只要这句,上面都不要 print(sys.path) # 打印当前的环境变量 sys.path.append(BASE_DIR) # 添加环境变量,这句也要。 print(sys.path) # 看看现在的环境变量是否有增加
实际使用时,我们只需要上面的2句就可以了。
作业
员工信息表:
staff_id | name | age | phone | dept | enroll_date |
1 | Adam Liu | 25 | 13562984561 | IT | 2013-04-01 |
2 | Barry Allen | 22 | 13659874522 | HR | 2015-05-03 |
3 | Clark Kent | 30 | 13156998456 | Sales | 2016-04-22 |
4 | Eddie Thawne | 40 | 13566942130 | HR | 2009-03-01 |
不过这个表可能是这样存在你的文件里的:
1,Adam Liu,25,13562984561,IT,2013-04-01
现需要对这个员工信息文件,实现增删改查操作
一、可进行模糊查询,语法至少支持下面3种:
- select name,age from staff_table where age > 22
- select * from staff_table where dept = "IT"
- select * from staff_table where enroll_date like "2013"
- 查到的信息,打印后,最后面还要显示查到的条数
二、可创建新员工纪录,以phone做唯一键,staff_id需自增
三、可删除指定员工信息纪录,输入员工id,即可删除
四、可修改员工信息,语法如下:
update staff_table set dept="Market" where dept = "IT"
注意:以上内容要充分使用函数,最大限度减少重复代码。