Json概述以及Python对json的相关操作:

什么是json:

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。

JSON建构于两种结构:

“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

jso官方说明参见:http://json.org/

Python操作json的标准api库参考:http://docs.python.org/library/json.html

对简单数据类型的encoding 和 decoding:

使用简单的json.dumps方法对简单数据类型进行编码,例如:

1

2

3

4

5

6

import json

obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]

encodedjson = json.dumps(obj)

print repr(obj)

print encodedjson

输出:

[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}]
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]

通过输出的结果可以看出,简单类型通过encode之后跟其原始的repr()输出结果非常相似,但是有些数据类型进行了改变,例如上例中的元组则转换为了列表。在json的编码过程中,会存在从python原始类型向json类型的转化过程,具体的转化对照如下:

json.dumps()方法返回了一个str对象encodedjson,我们接下来在对encodedjson进行decode,得到原始数据,需要使用的json.loads()函数:

1

2

3

4

decodejson = json.loads(encodedjson)

print type(decodejson)

print decodejson[4]['key1']

print decodejson

输出:

<type 'list'>
[1, 2, 3]

[[1, 2, 3], 123, 123.123, u'abc', {u'key2': [4, 5, 6], u'key1': [1, 2, 3]}]

loads方法返回了原始的对象,但是仍然发生了一些数据类型的转化。比如,上例中‘abc’转化为了unicode类型。从json到python的类型转化对照如下:

json.dumps方法提供了很多好用的参数可供选择,比较常用的有sort_keys(对dict对象进行排序,我们知道默认dict是无序存放的),separators,indent等参数。

排序功能使得存储的数据更加有利于观察,也使得对json输出的对象进行比较,例如:

1

2

3

4

5

6

7

8

9

10

data1 = {'b':789,'c':456,'a':123}

data2 = {'a':123,'b':789,'c':456}

d1 = json.dumps(data1,sort_keys=True)

d2 = json.dumps(data2)

d3 = json.dumps(data2,sort_keys=True)

print d1

print d2

print d3

print d1==d2

print d1==d3

输出:

{"a": 123, "b": 789, "c": 456}
{"a": 123, "c": 456, "b": 789}
{"a": 123, "b": 789, "c": 456}
False
True

上例中,本来data1和data2数据应该是一样的,但是由于dict存储的无序特性,造成两者无法比较。因此两者可以通过排序后的结果进行存储就避免了数据比较不一致的情况发生,但是排序后再进行存储,系统必定要多做一些事情,也一定会因此造成一定的性能消耗,所以适当排序是很重要的。

indent参数是缩进的意思,它可以使得数据存储的格式变得更加优雅。

1

2

3

data1 = {'b':789,'c':456,'a':123}

d1 = json.dumps(data1,sort_keys=True,indent=4)

print d1

输出:

{
    "a": 123,
    "b": 789,
    "c": 456
}

输出的数据被格式化之后,变得可读性更强,但是却是通过增加一些冗余的空白格来进行填充的。json主要是作为一种数据通信的格式存在的,而网络通信是很在乎数据的大小的,无用的空格会占据很多通信带宽,所以适当时候也要对数据进行压缩。separator参数可以起到这样的作用,该参数传递是一个元组,包含分割对象的字符串。

1

2

3

4

5

print 'DATA:', repr(data)

print 'repr(data)             :', len(repr(data))

print 'dumps(data)            :', len(json.dumps(data))

print 'dumps(data, indent=2)  :', len(json.dumps(data, indent=4))

print 'dumps(data, separators):', len(json.dumps(data, separators=(',',':')))

输出:

DATA: {'a': 123, 'c': 456, 'b': 789}
repr(data)             : 30
dumps(data)            : 30
dumps(data, indent=2)  : 46
dumps(data, separators): 25

通过移除多余的空白符,达到了压缩数据的目的,而且效果还是比较明显的。

另一个比较有用的dumps参数是skipkeys,默认为False。 dumps方法存储dict对象时,key必须是str类型,如果出现了其他类型的话,那么会产生TypeError异常,如果开启该参数,设为True的话,则会比较优雅的过度。

1

2

data = {'b':789,'c':456,(1,2):123}

print json.dumps(data,skipkeys=True)

输出:

{"c": 456, "b": 789}

处理自己的数据类型

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

json模块不仅可以处理普通的python内置类型,也可以处理我们自定义的数据类型,而往往处理自定义的对象是很常用的。

首先,我们定义一个类Person。

1

2

3

4

5

6

7

8

9

class Person(object):

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __repr__(self):

        return 'Person Object name : %s , age : %d' % (self.name,self.age)

if __name__  == '__main__':

    p = Person('Peter',22)

    print p

如果直接通过json.dumps方法对Person的实例进行处理的话,会报错,因为json无法支持这样的自动转化。通过上面所提到的json和python的类型转化对照表,可以发现,object类型是和dict相关联的,所以我们需要把我们自定义的类型转化为dict,然后再进行处理。这里,有两种方法可以使用。

方法一:自己写转化函数

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

'''

Created on 2011-12-14

@author: Peter

'''

import Person

import json

p = Person.Person('Peter',22)

def object2dict(obj):

    #convert object to a dict

    d = {}

    d['__class__'] = obj.__class__.__name__

    d['__module__'] = obj.__module__

    d.update(obj.__dict__)

    return d

def dict2object(d):

    #convert dict to object

    if'__class__' in d:

        class_name = d.pop('__class__')

        module_name = d.pop('__module__')

        module = __import__(module_name)

        class_ = getattr(module,class_name)

        args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args

        inst = class_(**args) #create new instance

    else:

        inst = d

    return inst

d = object2dict(p)

print d

#{'age': 22, '__module__': 'Person', '__class__': 'Person', 'name': 'Peter'}

o = dict2object(d)

print type(o),o

#<class 'Person.Person'> Person Object name : Peter , age : 22

dump = json.dumps(p,default=object2dict)

print dump

#{"age": 22, "__module__": "Person", "__class__": "Person", "name": "Peter"}

load = json.loads(dump,object_hook = dict2object)

print load

#Person Object name : Peter , age : 22

上面代码已经写的很清楚了,实质就是自定义object类型和dict类型进行转化。object2dict函数将对象模块名、类名以及__dict__存储在dict对象里,并返回。dict2object函数则是反解出模块名、类名、参数,创建新的对象并返回。在json.dumps 方法中增加default参数,该参数表示在转化过程中调用指定的函数,同样在decode过程中json.loads方法增加object_hook,指定转化函数。

方法二:继承JSONEncoder和JSONDecoder类,覆写相关方法

JSONEncoder类负责编码,主要是通过其default函数进行转化,我们可以override该方法。同理对于JSONDecoder。

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

'''

Created on 2011-12-14

@author: Peter

'''

import Person

import json

p = Person.Person('Peter',22)

class MyEncoder(json.JSONEncoder):

    def default(self,obj):

        #convert object to a dict

        d = {}

        d['__class__'] = obj.__class__.__name__

        d['__module__'] = obj.__module__

        d.update(obj.__dict__)

        return d

class MyDecoder(json.JSONDecoder):

    def __init__(self):

        json.JSONDecoder.__init__(self,object_hook=self.dict2object)

    def dict2object(self,d):

        #convert dict to object

        if'__class__' in d:

            class_name = d.pop('__class__')

            module_name = d.pop('__module__')

            module = __import__(module_name)

            class_ = getattr(module,class_name)

            args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args

            inst = class_(**args) #create new instance

        else:

            inst = d

        return inst

d = MyEncoder().encode(p)

o =  MyDecoder().decode(d)

print d

print type(o), o

对于JSONDecoder类方法,稍微有点不同,但是改写起来也不是很麻烦。看代码应该就比较清楚了。

Json概述以及python对json的相关操作(至尊宝错过了紫霞仙子,难道你也要错过python对json的相关操作吗?)相关推荐

  1. python列表元祖字典集合运算_Python基础5:列表 元祖 字典 集合 Json

    [ 列表] 列表(list)是Python以及其他语言中最常用到的数据结构之一.Python使用使用中括号 [ ] 来解析列表. 列表是可变的(mutable)--即:可以改变列表的内容. 相关操作: ...

  2. Newtonsoft.Json 概述

    有时候,在前后台数据交互或者APP与后台交互的时候,我们通常会使用Json进行数据交互,为此会使用到Newtonsoft.Json.dll 这个类库,这个类库非微软官方,但是下载量已经超过了数十万次, ...

  3. python中常用的序列化模块_第六章 常用模块(5):python常用模块(序列化模块:pickle,json,shelve,xml)...

    6.3.7 序列化模块 (pickle,json,shelve,xml) 文件写入,数据传输时,我们都是以字符串形式写入的(因为字符串可以encode成bytes). 那其他类型(比如字典,列表等)想 ...

  4. 黑马程序员python笔记_#华为云·寻找黑马程序员# 如何实现一个优雅的Python的Json序列化库...

    [小宅按]在Python的世界里,将一个对象以json格式进行序列化或反序列化一直是一个问题.Python标准库里面提供了json序列化的工具,我们可以简单的用json.dumps来将一个对象序列化. ...

  5. 《Ext JS权威指南》——1.2节JSON概述

    1.2 JSON概述 1.2.1 认识JSON XML虽好,可作为数据交换格式,有时会喧宾夺主,标记比数据还多,徒增流量.更重要的是,在JavaScript中处理XML实在太不便利了.而JSON,没有 ...

  6. 前端项目中package.json到底是什么,又充当着什么作用呢?一文来带你了解package.json!

    大家好,我是纸飞机,想必大家都在项目中经常看见package.json.package-lock.json.node_modules这三剑客,那么他们到底是什么呢?又有什么作用呢?今天就来带你们理一遍 ...

  7. Python知识点以及相关练习题(四万余字总结)期末Python知识点总结

    Python知识点以及相关练习题 一.变量和类型 二.分支结构 三.循环结构 四.函数和模块的使用 五.字符串和常用数据结构 六.面向对象编程基础 七.面向对象进阶(含小游戏案例源码) 一.变量和类型 ...

  8. python不会英语不会数学怎么自学-26岁了,自学Python怎么样?

    数学与应用数学专业转行Python的话还是很有优势的.首先来了解一下Python的可就业方向有那些,找到方向后.了解重点学习的知识点,是比较有效率的学习方式. 一.Python就业方向 /> 来 ...

  9. Python|并发编程|爬虫|单线程|多线程|异步I/O|360图片|Selenium及JavaScript|Scrapy框架|BOM 和 DOM 操作简介|语言基础50课:学习(12)

    文章目录 系列目录 原项目地址 第37课:并发编程在爬虫中的应用 单线程版本 多线程版本 异步I/O版本 总结 第38课:抓取网页动态内容 Selenium 介绍 使用Selenium 加载页面 查找 ...

最新文章

  1. char varchar nvarchar区别
  2. 分布式配置中心disconf第三部(基于xml配置的实现原理)
  3. App研发录读后总结(一)
  4. 深度学习100例-卷积神经网络(CNN)识别验证码 | 第12天
  5. 2020-12-09 深度学习 卷积神经网络中感受野的详细介绍
  6. 每天一道LeetCode-----删除序列中指定元素,将满足要求的元素移动到前面
  7. ANDROID自定义视图——onMeasure流程,MeasureSpec详解
  8. java内存泄漏案例_寻找内存泄漏:一个案例研究
  9. 前端学习(3321):瀑布流的方式演示
  10. hibernate框架 最新_2020年最新Java后端学习路线,送给正在入门学习Java的你!
  11. 摘来的去视频网站的广告方法
  12. Ztree 改 节点
  13. GetAdaptersInfo获取网卡信息
  14. 2021-6-7-今日收获
  15. 寄存器 内存 磁盘 读取速度
  16. MOOC微信小程序开发从入门到实践~笔记
  17. xinetd的安装配置
  18. python自制小游戏_教你用Python自制拼图小游戏,一起来制作吧
  19. 画图神器-drawio(配合markdown使用更佳)
  20. springboot项目在线程中调用service访问数据库

热门文章

  1. 浅谈微信公众号怎么涨粉丝
  2. linux通过mailx发送邮件
  3. gravity和layout_gravity的区别(有时使用layout_gravity=center时失效的原因)
  4. 关于idea+mybatis+springcloud+swagger2+Apollo 踩得小坑
  5. 基于SPI的OLED温湿度显示
  6. 【洛谷】 P1240 诸侯安置(递推)
  7. 测试透射晶格分析的软件,透射电镜(TEM)电子衍射在晶体结构分析中的应用三...
  8. 田园项目tabber标签栏使用
  9. mysql locate不走索引_面试--mysql的模糊查询优化、like、locate、position、instr、find_in_set...
  10. 花老湿学习OpenCV:分水岭原理和实现watershed()