Python 基础 - 4.7 json模块

什么叫序列化?

序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes

 

什么叫反序列化?

把字符转成内存数据类型,就叫做反序列化

 

JSON 函数

使用 JSON 函数需要导入 json 库:import json

函数描述
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象

为什么要序列化?

你打游戏过程中,打累了,停下来,关掉游戏、想过2天再玩,2天之后,游戏又从你上次停止的地方继续运行,你上次游戏的进度肯定保存在硬盘上了,是以何种形式呢?游戏过程中产生的很多临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,需要存下来?你如何存?把列表变成文件里的多行多列形式?那嵌套字典呢?根本没法存。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。

用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换
  • pickle,用于python特有的类型 和 python的数据类型间进行转换

Json模块提供了四个功能:dumps、dump、loads、load

pickle模块提供了四个功能:dumps、dump、loads、load

只是把数据类型转成字符串到内存的意思?

    json.dumps   json.loads

1. 把内存的数据,通过网络,共享给远程其他人

2. 定义了不同语言的之前的交互规则

    - 纯文件,坏处,不能共享复杂的数据类型

    - xml,坏处,占用空间大

    - json ,简单, 可读性好,占用空间小

json dumps,loads是针对内存数据转换

In [204]: import json

In [205]: dic
Out[205]: {'name': 'cmz', 'sex': 'male', 'age': 30}

In [206]: s = json.dumps(dic) # 内存的数据转换成字符串

In [207]: s
Out[207]: '{"name": "cmz", "sex": "male", "age": 30}'

In [208]: type(s)
Out[208]: str

In [209]: back_s = json.loads(s) # 将内存的数据转换成字典

In [210]: back_s
Out[210]: {'name': 'cmz', 'sex': 'male', 'age': 30}

 

json dump,load是针对文件转换

In [239]: import json

In [240]: dic
Out[240]: {'name': 'cmz', 'sex': 'male', 'age': 30}

In [241]: with open('json.file','w') as fd:  # 序列化到文件
   .....:     json.dump(dic,fd)  
   .....:     

In [242]: cat json.file
{"name": "cmz", "sex": "male", "age": 30}
In [243]: with open('json.file','r') as fd:  # 反序列化到内存
   .....:     bak_data = json.load(fd)
   .....:     

In [244]: bak_data
Out[244]: {'name': 'cmz', 'sex': 'male', 'age': 30}

In [245]: type(bak_data)
Out[245]: dict



另一种简便方法

In [22]: cmz = '123'

In [23]: json.dump(cmz,open('cmz.json','w'))    # 直接存储

In [24]: cat cmz.json
"123"

In [25]: cc = json.load(open('cmz.json','r'))   #直接取出

In [26]: cc
Out[26]: '123'
In [27]: type(cc)
Out[27]: str
In [252]: dct='{"1":"111"}'
In [253]: print(json.loads(dct))
{'1': '111'}
无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

注意点

In [271]: dic = '{"name":"cmz","age":30}'

In [272]: json.loads(dic)
Out[272]: {'name': 'cmz', 'age': 30}

In [273]: dic = "{'name':'cmz','age':30}"    # json不认识单引号

In [274]: json.loads(dic)
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
<ipython-input-274-fe1545dfe2f3> in <module>()
----> 1 json.loads(dic)

/usr/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    317             parse_int is None and parse_float is None and
    318             parse_constant is None and object_pairs_hook is None and not kw):
--> 319         return _default_decoder.decode(s)
    320     if cls is None:
    321         cls = JSONDecoder

/usr/lib/python3.5/json/decoder.py in decode(self, s, _w)
    337 
    338         """
--> 339         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340         end = _w(s, end).end()
    341         if end != len(s):

/usr/lib/python3.5/json/decoder.py in raw_decode(self, s, idx)
    353         """
    354         try:
--> 355             obj, end = self.scan_once(s, idx)
    356         except StopIteration as err:
    357             raise JSONDecodeError("Expecting value", s, err.value) from None

JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
In [280]:  dic = {'name':'cmz','age':30}
In [281]: dic_json = json.dumps(dic)
In [282]: dic_back = json.loads(dic_json)
In [283]: dic_back
Out[283]: {'name': 'cmz', 'age': 30}
In [284]: dic_json
Out[284]: '{"name": "cmz", "age": 30}'

 

pickle类似

内存转换

In [292]:  dic = {'name':'cmz','age':30}

In [293]: dic_pickle = pickle.dumps(dic)  # 内存中的数据序列化到硬盘

In [294]: dic_pickle
Out[294]: b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00cmzq\x02X\x03\x00\x00\x00ageq\x03K\x1eu.'

In [295]: dic_pickle_bak = pickle.loads(dic_pickle)  # 反序列化到内存

In [296]: dic_pickle_bak
Out[296]: {'name': 'cmz', 'age': 30}

In [297]: type(dic_pickle)
Out[297]: bytes

In [298]: type(dic_pickle_bak)
Out[298]: dict

文件

In [306]:  dic = {'name':'cmz','age':30}

In [307]: with open('pickle.file','wb') as fd:  #注意是w是写入str,wb是写入bytes,j是'bytes'
   .....:     pickle.dump(dic,fd)
   .....:     
In [309]: cat pickle.file
}q(XnameqXcmzqXageqKu.

In [311]: with open('pickle.file','rb') as fd:
              data = pickle.load(fd)
   .....:     

In [312]: data
Out[312]: {'name': 'cmz', 'age': 30}
In [313]: type(data)
Out[313]: dict

 

json vs pickle:

JSON:

优点:跨语言、体积小

缺点:只能支持int\str\list\tuple\dict

 

Pickle:

优点:专为python设计,支持python所有的数据类型

缺点:只能在python中使用,存储数据占空间大

posted @ 2018-01-26 11:23  Love_always_online  阅读(245)  评论(0编辑  收藏  举报