json

json文件的使用方式

json 全称 JavaScript object notation,是一种轻量级的数据交换格式。python中的json模块提供了json数据的处理功能。

python中最常用的基本数据结构之一就是字典,其典型结构如下:

d = {
    'a': 123,
    'b': {
        'x': ['A', 'B', 'C']
    }
}

而json的结构如下:

{
    "a": 123,
    "b": {
        "x": ["A", "B", "C"]
    }
}

可以看到,dict和json非常接近,而python中的json库提供的主要功能,也是两者之间的转化。json中,字符串只能放在双引号中。如果被处理的python字符串是包含在双引号中的,那么json中的双引号就需要转义,否则会报错。

import json
jo = json.loads('{"a": 123}')
jo = json.loads("{\"a\": 123}")

json read

今天出的问题原来是把py文件命名成了模块名而导致的。

对于内容是json数据的bytes和bytearray,json.loads方法也可以处理:

import json
json.loads('{"a": 123}'.encode('UTF-8'))
{'a': 123}
json.loads(bytearray('{"a": 123}', 'UTF-8'))
{'a': 123}

数据类型转换

json可以表示四种主类型数据:

  • 字符串 string
  • 数字 number
  • 布尔值 boolean
  • 空值 null

以及两种数据结构:

  • 对象 object
  • 数组 array

默认实现中,json和python之间的数据转换关系对应如下

jsonpython
objectdict
arraylist
stringstr
number(int)int
number(real)float
trueTrue
nullNone
NaNfloat(‘nan’)
Infinityfloat(‘inf’)
-Infinityfloat(’-inf’)

示例如下:

json_exp = """
{
    "obj":{
        "str":"abc",
        "int": 123,
        "float": -3.1415926,
        "bool_true": true,
        "bool false": false,
        "null": null,
        "array": [1, 2, [3]],
        "NaN": NaN,
        "Infinity": Infinity,
        "-Infinity": -Infinity
    }
}
"""
jo = json.loads(json_exp)
print(jo)
print(jo['obj']['array'][2][0])

stdout:

C:\Users\winter\Anaconda2\envs\tensorflow\python.exe E:/PycharmProjects/CONSOLE/Json.py
{'obj': {'str': 'abc', 'int': 123, 'float': -3.1415926, 'bool_true': True, 'bool false': False, 'null': None, 'array': [1, 2, [3]], 'NaN': nan, 'Infinity': inf, '-Infinity': -inf}}
3

自定义json对象转换类型

json.loads()默认将json中的对象数据转化为dict类型,object_hook参数可以用来改变构造出的对象。object_hook接受一个函数,函数的输入参数为json中对象数据转换出的dict对象。当json中的对象有嵌套时,json.loads()方法会按照深度优先的方式遍历对象树,将各层的对象数据传递给object_hook叶节点的json对象构造出的python对象,会作为父节点的一个值,传递给父节点的object_hook方法

class MyJSONObj:
    def __init__(self, x):
        self.x = x
def my_json_obj_hook(data):
    print('obj_hook data: %s' % data)
    return MyJSONObj(data['x'])

result = json.loads('{"x": {"x": 11, "y": 12}, "y": {"x": 21, "y":22}}', object_hook=my_json_obj_hook)
print(type(result), result.x.x)

stdout:

obj_hook data: {'x': 11, 'y': 12}
obj_hook data: {'x': 21, 'y': 22}
obj_hook data: {'x': <__main__.MyJSONObj object at 0x000001BCDCA8DDD8>, 'y': <__main__.MyJSONObj object at 0x000001BCDCA8DE10>}
<class '__main__.MyJSONObj'> 11

类似地,还有自定义json数字转换类型:

jsonpara
objobject_hook
floatparse_float
intparse_int
NaN…parse_constant

非对象值

json.loads('123')
123
json.loads('null')
json.loads('NaN')
nan

重复键名

在同一级json对象中,不应当出现重复的键名。不过,json规范中没有给出这种情况的处理标准,在json.loads()中,当json数据中有重复键名时,则前面的键名会被后面的键名覆盖

json.loads('{"a": 123, "b": "ABC", "a": 321}')
{'a': 321, 'b': 'ABC'}

处理json数据文件

json.load(json_file)

除了文件类型对象,只要是实现了read方法的类文件对象,也可以作为json.load()的参数。

json write

json.dumps(python_string)

json.dumps({'a': 123, 'b':234})
'{"a": 123, "b": 234}'

ps.json.dumps()ensure_ascii参数用来控制生成的json字符串的编码,默认值为True,此时,所有非ascii编码均会进行转义。更改为False后会保持原有编码UTF-8

json.dumps({'a': 123, '张晓龙':234})
'{"a": 123, "\\u5f20\\u6653\\u9f99": 234}'
json.dumps({'a': 123, '张晓龙':234}, ensure_ascii=False)
'{"a": 123, "张晓龙": 234}'

json字符串输出格式

json.dumps()方法的indent参数可以用来控制json字符串的换行和缩进效果。

indent效果example
None咩有缩进效果{"a": 123, "b": {"x": 321, "y": "ABC"}}
<=0换行示例1
正整数以指定数量的空格为单位在对象层次间进行缩进示例2
str以str内容为单位进行缩进示例3

示例1:

print(json.dumps(jc, indent=0))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}
print(json.dumps(jc, indent=-2))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}

示例2:

print(json.dumps(jc, indent=1))
{
 "a": 123,
 "b": {
  "x": 321,
  "y": "ABC"
 }
}
print(json.dumps(jc, indent=2))
{
  "a": 123,
  "b": {
    "x": 321,
    "y": "ABC"
  }
}

示例3:

print(json.dumps(jc, indent='\t'))
{
	"a": 123,
	"b": {
		"x": 321,
		"y": "ABC"
	}
}
print(json.dumps(jc, indent='long'))
{
long"a": 123,
long"b": {
longlong"x": 321,
longlong"y": "ABC"
long}
}

转换自定义Python对象

json.dumps的默认实现只能转换Dictionary类型的对象。如果想要转换自定义对象, 需要使用default参数。这个参数接收一个函数,这个函数的参数是一个要转换的Python对象, 返回值是能够表示这个Python对象的Dictionary对象。default函数会从对象引用树的顶层开始, 逐层遍历整个对象引用树。因此,不用自己实现对象树的遍历逻辑,只需要处理当前层次的对象。 如下例所示:

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def my_default(o):
    if isinstance(o, MyClass):
        print('%s.y: %s' % (type(o), o.y))
        return {'x': o.x, 'y': o.y}
    print(o)
    return o

obj = MyClass(x=MyClass(x=1, y=2), y=11)
jo = json.dumps(obj, default=my_default)
print(jo)

stdout:

C:\Users\winter\Anaconda2\envs\tensorflow\python.exe E:/PycharmProjects/CONSOLE/Json.py
<class '__main__.MyClass'>.y: 11
<class '__main__.MyClass'>.y: 2
{"x": {"x": 1, "y": 2}, "y": 11}

写入json文件

json_exp = """
{
    "obj":{
        "str":"abc",
        "int": 123,
        "float": -3.1415926,
        "bool_true": true,
        "bool false": false,
        "null": null,
        "array": [1, 2, 3]
    }
}
"""
json_exp = json.loads(json_exp)
print(json_exp)
jo = json.dumps(json_exp, indent='\t')
print(jo)
with open('diy.json', 'w') as f:
    json.dump(json_exp, f, indent='\t')

diy.json

{
	"obj": {
		"str": "abc",
		"int": 123,
		"float": -3.1415926,
		"bool_true": true,
		"bool false": false,
		"null": null,
		"array": [
			1,
			2,
			3
		]
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值