$ python-json模块的基本用法
准备工作
import json
# 准备数据:
d = dict(name = 'Tom',age = 18)
json_str = '{"name":"Tom","age":18}'
# 注:json字符串中的引号必须为双引号,若为单引号会转换出错。
json数据类型和python数据类型的对应关系
- {} <——> dict
- [] <——> list
- "string" <——> "str"或u"unicode"
- 123.4 <——> int或float
- true/false <——> True/False
- null <——> None
常用方法
把字典转换成json字符串
ret = json.dumps(d)
print ret
print type(ret)
{"age": 18, "name": "Tom"}
<type 'str'>
把json字符串转成字典
ret = json.loads(json_str)
print ret
print type(ret)
{u'age': 18, u'name': u'Tom'}
<type 'dict'>
把字典转换成json字符串并写入文件
with open('out.txt','w+') as f:
json.dump(d,f)
从文件中读取一个json字符串并转换为字典
# 文件(out.txt)内容:{"age": 18, "name": "Tom"}
with open('out.txt','r') as f:
ret = json.load(f)
print ret
print type(ret)
{u'age': 18, u'name': u'Tom'}
<type 'dict'>
自定义对象转成json字符串
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
s = Student('Tom',18)
print json.dumps(s)
# 输出:
# TypeError: <__main__.Student object at 0x7f7ab808cf10> is not JSON serializable
出错原因:Student对象不是一个可序列化为json的对象。
- 解决方法1:写个转换函数
def student2dict(std):
return {'name':std.name,'age':std.age}
print json.dumps(s,default = student2dict)
{"age": 18, "name": "Tom"}
- 解决方法2:传入Student对象内置属性:dict
print json.dumps(s,default = lambda obj:obj.__dict__)
{"age": 18, "name": "Tom"}
json字符串转换为自定义对象
def dict2student(d):
return Student(d['name'],d['age'])
ret = json.loads(json_str,object_hook = dict2student)
print ret
print ret.__dict__
print type(ret)
<__main__.Student object at 0x7f7aaa713ad0>
{'age': 18, 'name': u'Tom'}
<class '__main__.Student'>
补充
更好地输出json
json.dumps(json.loads(json_str),indent = 4) # indent为缩进的字符数
'{\n "age": 18, \n "name": "Tom"\n}'
保持json字符串中属性的顺序
from collections import OrderedDict
data = json.loads(json_str,object_pairs_hook = OrderedDict)
print data
OrderedDict([(u'name', u'Tom'), (u'age', 18)])
引申:object_pairs_hook是个什么玩意?
这时候就有疑惑了,这个object_pairs_hoo参数是个什么玩意?为什么加上:object_pairs_hook = OrderedDict这样一个参数,解析的字典就可以有序了?
为了揭开这个谜团,首先去看看json.loads()函数文档,发现文档中对object_pairs_hook参数的描述是这样的:
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders that rely on the
order that the key and value pairs are decoded (for example,
collections.OrderedDict will remember the order of insertion). If
``object_hook`` is also defined, the ``object_pairs_hook`` takes priority.
大致意思就是:object_pairs_hook实际上是一个函数对象(钩子函数),它的入参是json文本的有序键值对的列表(ordered list of pairs),返回值是一个经过自定义处理的值,json.loads()函数的返回值也会是这个钩子函数的返回值。
说了半天估计也没看明白,那就实际写个demo试一把,先看最简单的一个demo:
# coding:utf-8
import json
def deal_with_pairs(pairs):
'''
自定义的钩子函数,处理从json文本中解析出的有序键值对列表
:param pairs: 从json文本中解析出的有序键值对列表
:return: 自定义的对象
'''
return pairs
json_str = '{"a":"111","b":"222"}'
data = json.loads(json_str,object_pairs_hook = deal_with_pairs)
print data
输出:
[(u'a', u'111'), (u'b', u'222')]
可以看出,输出的就是json文本中的有序键值对列表。
下面继续看一个稍微复杂一点的demo:
# coding:utf-8
import json
# 存放json中重复的key列表
duplicate_keys = []
def deal_with_pairs(pairs):
'''
自定义的钩子函数,处理从json文本中解析出的有序键值对列表
:param pairs: 从json文本中解析出的有序键值对列表
:return: 自定义的对象
'''
data = {}
for k,v in pairs:
# 如果键已经在data的键中存在了,那么把它添加到duplicate_keys列表
if k in data:
duplicate_keys.append(k)
# 否则添加到data中
else:
data[k] = v
return data
json_str = '{"a":"111","b":"222","a":"345"}'
data = json.loads(json_str,object_pairs_hook = deal_with_pairs)
print data
print duplicate_keys
输出:
{u'a': u'111', u'b': u'222'}
[u'a']
可以看出,上面这个程序的作用就是找出了json文本中有哪些键是重复的。
最后再来一个嵌套的有重复key的json字符串,来看看效果:
# coding:utf-8
import json
# 存放json中重复的key列表
duplicate_keys = []
def deal_with_pairs(pairs):
'''
自定义的钩子函数,处理从json文本中解析出的有序键值对列表
:param pairs: 从json文本中解析出的有序键值对列表
:return: 自定义的对象
'''
print 'pairs is: {0}'.format(pairs)
data = {}
for k,v in pairs:
# 如果键已经在data的键中存在了,那么把它添加到duplicate_keys列表
if k in data:
duplicate_keys.append(k)
# 否则添加到data中
else:
data[k] = v
return data
json_str = '{"a":"111","b":{"b1":"b111","b2":"b222","b1":"b123"},"a":"345"}'
data = json.loads(json_str,object_pairs_hook = deal_with_pairs)
print data
print duplicate_keys
输出:
pairs is: [(u'b1', u'b111'), (u'b2', u'b222'), (u'b1', u'b123')]
pairs is: [(u'a', u'111'), (u'b', {u'b1': u'b111', u'b2': u'b222'}), (u'a', u'345')]
{u'a': u'111', u'b': {u'b1': u'b111', u'b2': u'b222'}}
[u'b1', u'a']
可以看出这里输出了两个pairs列表,第一个是内层的子json的键值对列表,第二个是外层的json键值对列表。最终查找出来的重复的键有:'b1'和'a',和我们的预期相符。
随机推荐
- 第一百五十四节,封装库--JavaScript,表单验证--提交验证
封装库--JavaScript,表单验证--提交验证 将表单的所有必填项,做一个判断函数,填写正确时返回布尔值 最后在提交时,判断每一项是否正确,全部正确才可以 提交 html <div id= ...
- 再谈Unity调用Android的Activity
这段时间在研究Unity4.3开发环境下.怎样调用由Android SDK4.4.2写的Activity.參考了非常多网上的博客.百度出了几十篇大部分都是转载雨松MOMO的,这里必须向雨松MOMO表示 ...
- ubuntu安装jdk详细教程
ubuntu14 安装jdk1.7 具体步骤参详了如下链接: http://www.cnblogs.com/plinx/archive/2013/06/01/3113106.html 1.到 Sun ...
- Multiview
新建3个ViewController的类 新建main.stroyboard,并配置好相应的布局(编辑界面,连接视图与类,ViewController的Storyboard ID,连接3个Button ...
- 用MathType编辑反三角函数的方法
在使用文档写数学类的文章时候,常常会涉及到一些数学公式,由于数学公式中包含了很多的数学符号,如果使用文档自带的公式编辑器往往会发现很多的符号都不全或者不符合自己的要求.这个时候就需要一款专业的数学公式 ...
- 监视EF生成SQL的方法(log , SqlServerProfile)
大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...
- 上传图片到数据库,读取数据库中图片并显示(C#)
from:http://blog.csdn.net/bfcady/article/details/2622701 思路:建立流对象,将上传图片临时保存到byte数组中,再用SQL语句将其保存到数据库中 ...
- 获取TXT文件,解决读取TXT乱码问题,查找所输入字是否在TXT文件中,
/// <summary> /// 查看是否存在 /// </summary> /// <param name="str"></param ...
- JS制作一个通用的商城版历史浏览记录
正在开发一个b2c的国外商城,昨天做了一个历史浏览记录发出来跟大家分享一下. JS: //cookie相关函数 function getCookieVal(offset) { var endst ...
- Oracle Instant Client的安装和使用
转自:https://www.cnblogs.com/chinalantian/archive/2011/09/09/2172145.html 根据自己需求到Oracle网站(http://www.o ...