来源 http://www.cnblogs.com/qq78292959/p/3467937.html 

什么是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. import json
  2.  
  3. obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]
  4. encodedjson = json.dumps(obj)
  5. print repr(obj)
  6. 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. decodejson = json.loads(encodedjson)
  2. print type(decodejson)
  3. print decodejson[4]['key1']
  4. 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. data1 = {'b':789,'c':456,'a':123}
  2. data2 = {'a':123,'b':789,'c':456}
  3. d1 = json.dumps(data1,sort_keys=True)
  4. d2 = json.dumps(data2)
  5. d3 = json.dumps(data2,sort_keys=True)
  6. print d1
  7. print d2
  8. print d3
  9. print d1==d2
  10. 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. data1 = {'b':789,'c':456,'a':123}
  2. d1 = json.dumps(data1,sort_keys=True,indent=4)
  3. print d1

输出:


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

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

  1. print 'DATA:', repr(data)
  2. print 'repr(data)             :', len(repr(data))
  3. print 'dumps(data)            :', len(json.dumps(data))
  4. print 'dumps(data, indent=2)  :', len(json.dumps(data, indent=4))
  5. 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. data = {'b':789,'c':456,(1,2):123}
  2. print json.dumps(data,skipkeys=True)

输出:

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

处理自己的数据类型

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

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

  1. class Person(object):
  2.     def __init__(self,name,age):
  3.         self.name = name
  4.         self.age = age
  5.     def __repr__(self):
  6.         return 'Person Object name : %s , age : %d' % (self.name,self.age)
  7. if __name__  == '__main__':
  8.     p = Person('Peter',22)
  9.     print p

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

方法一:自己写转化函数

  1. '''
  2. Created on 2011-12-14
  3. @author: Peter
  4. '''
  5. import Person
  6. import json
  7.  
  8. p = Person.Person('Peter',22)
  9.  
  10. def object2dict(obj):
  11.     #convert object to a dict
  12.     d = {}
  13.     d['__class__'] = obj.__class__.__name__
  14.     d['__module__'] = obj.__module__
  15.     d.update(obj.__dict__)
  16.     return d
  17.  
  18. def dict2object(d):
  19.     #convert dict to object
  20.     if'__class__' in d:
  21.         class_name = d.pop('__class__')
  22.         module_name = d.pop('__module__')
  23.         module = __import__(module_name)
  24.         class_ = getattr(module,class_name)
  25.         args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args
  26.         inst = class_(**args) #create new instance
  27.     else:
  28.         inst = d
  29.     return inst
  30.  
  31. d = object2dict(p)
  32. print d
  33. #{'age': 22, '__module__': 'Person', '__class__': 'Person', 'name': 'Peter'}
  34.  
  35. o = dict2object(d)
  36. print type(o),o
  37. #<class 'Person.Person'> Person Object name : Peter , age : 22
  38.  
  39. dump = json.dumps(p,default=object2dict)
  40. print dump
  41. #{"age": 22, "__module__": "Person", "__class__": "Person", "name": "Peter"}
  42.  
  43. load = json.loads(dump,object_hook = dict2object)
  44. print load
  45. #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. Created on 2011-12-14
  3. @author: Peter
  4. '''
  5. import Person
  6. import json
  7.  
  8. p = Person.Person('Peter',22)
  9.  
  10. class MyEncoder(json.JSONEncoder):
  11.     def default(self,obj):
  12.         #convert object to a dict
  13.         d = {}
  14.         d['__class__'] = obj.__class__.__name__
  15.         d['__module__'] = obj.__module__
  16.         d.update(obj.__dict__)
  17.         return d
  18.  
  19. class MyDecoder(json.JSONDecoder):
  20.     def __init__(self):
  21.         json.JSONDecoder.__init__(self,object_hook=self.dict2object)
  22.     def dict2object(self,d):
  23.         #convert dict to object
  24.         if'__class__' in d:
  25.             class_name = d.pop('__class__')
  26.             module_name = d.pop('__module__')
  27.             module = __import__(module_name)
  28.             class_ = getattr(module,class_name)
  29.             args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args
  30.             inst = class_(**args) #create new instance
  31.         else:
  32.             inst = d
  33.         return inst
  34.  
  35.  
  36. d = MyEncoder().encode(p)
  37. o =  MyDecoder().decode(d)
  38.  
  39. print d
  40. print type(o), o

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

python json操作的更多相关文章

  1. 【转】python 历险记(四)— python 中常用的 json 操作

    [转]python 历险记(四)— python 中常用的 json 操作 目录 引言 基础知识 什么是 JSON? JSON 的语法 JSON 对象有哪些特点? JSON 数组有哪些特点? 什么是编 ...

  2. python 历险记(四)— python 中常用的 json 操作

    目录 引言 基础知识 什么是 JSON? JSON 的语法 JSON 对象有哪些特点? JSON 数组有哪些特点? 什么是编码和解码? 常用的 json 操作有哪些? json 操作需要什么库? 如何 ...

  3. python json 数据操作

    python 有专门针对 json 操作的函数 #!/usr/bin/python3 import json mytest_js = { "a" : 1, "b" ...

  4. Python中的json操作

    Python中的json操作 标签(空格分隔): python 编码 json 字符串前缀问题 字符串前缀可以有r,u r:表示原始(raw)字符串,比如'\n'不会被转义.常用于正则. u:表示un ...

  5. python json序列化与反序列化操作

    python json序列化与反序列化操作 # dumps() dict-->str 序列化 # loads() str---dict 反序列化 result1 = json.dumps({'a ...

  6. python使用笔记006-函数+json操作

    一.函数 函数:提高代码的复用性 1.1 函数的定义 1 def hello(): 2 print('hello') 3 print('fdsfjslkfs') 4 5 #函数不调用就不会执行 6 h ...

  7. 【2019.6.2】python:json操作、函数、集合、random()等

    一.json操作: json就是一个字符串,从文件中读取json,必须是json格式.j'son串中必须是双引号,不能有单引号,单引号不能转换 1.1使用: import json #使用json先引 ...

  8. python语言(三)文件修改、函数、json操作、监控日志代码、高效读取文件

    1.文件操作(2)   代码 f = open('a.txt','a') # "a" 如果源文件不在,会自动创建 f.write('abc') result = f.read() ...

  9. Json操作(DynamicJson)

    Json的简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了 ...

随机推荐

  1. WCF Security(转载)

    WCF Security 主要包括 "Transfer Security"."Access Control"."Auditing" 几个部分 ...

  2. Issue 0:发刊词

    最近读吴军博士的文章,很受感悟.知识的成体系地积累过程对一个人的素养提高很有帮助,所以打算开通这本电子期刊,以一周一篇文章的形式汇总今后的知识体系. 宗旨:及时和团队讨论,反馈:善于利用工具.时间越长 ...

  3. jQuery源代码学习之九—jQuery事件模块

    jQuery事件系统并没有将事件坚挺函数直接绑定在DOM元素上,而是基于事件缓存模块来管理监听函数的. 二.jQuery事件模块的代码结构 //定义了一些正则 // // //jQuery事件对象 j ...

  4. js统计,然后去重例子

    var list=new Array(); for(var i=0;i<result.length;i++){ examsubject=result[i].examsubject; list.a ...

  5. Android四大核心组件之ContentProvider

    实验内容 学习ContextProvider用法 编码实现简单ContextProvider功能 实验要求 通过简单代码了解ContextProvider功能和用法 实验步骤 ContextProvi ...

  6. dmidecode常用参数

    dmidecode常用参数详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. dmidecode这个命令真是神器啊,他能快速的获取服务器的硬件信息,而且这个命令有很多的花式玩法,今 ...

  7. front-end plugin, generate pdf with html5 and jquery

    http://www.jqcool.net/jquery-jspdf.html[from this site] <html> <head></head> <s ...

  8. Ubuntu 16.04 Steam

    Ubuntu 16.04安装Steam,直接去Steam官网下载客户端安装包即可.

  9. 基于webpack使用ES6新特性(转载)

    本文转载自: http://www.tuicool.com/articles/vye2ea6

  10. vmware workstation unrecoverable error: (vmui)报错解决方法

    实验室7月份刚换了电脑,之前一直用vmware来跑linux搞嵌入式开发,无论是宿舍的笔记本,还是之前用的旧台式机,都可以妥妥的跑vmware没有问题,结果换了新电脑之后,装上vmware works ...