当前位置:首页 > 技术分析 > 正文内容

python散装笔记——49: JSON 模块

ruisui883个月前 (01-23)技术分析20

1: 将数据存储到文件中

以下代码段将 d 中存储的数据编码为 JSON 格式,并将其存储到文件中(用文件的实际名称替换 filename )。

import json

d = {
  'foo': 'bar',
  'alice': 1,
  'wonderland': [1, 2, 3]
}

with open(filename, 'w') as f:
  json.dump(d, f)

2: 从文件中读取数据

以下代码段打开一个 JSON 编码文件(用文件的实际名称替换 filename ),并返回存储在文件中的对象。

import json

with open(filename, 'r') as f:
  d = json.load(f)

3: 格式化 JSON 输出结果

假设我们有以下数据

>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

仅仅将其转换为 JSON 并没有什么特别之处:

print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

设置缩进以获得更漂亮的输出

如果我们想要漂亮的打印效果,可以设置缩进大小:

>>> print(json.dumps(data, indent=2))
{
  "cats": [
    {
      "name": "Tubbs",
      "color": "white"
    },
    {
      "name": "Pepper",
      "color": "black"
    }
  ]
}

按字母顺序排列键值,以获得一致的输出结果 默认情况下,输出中的键值顺序是未定义的。我们可以按字母顺序排列,确保输出结果始终一致:

print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}

剔除空白以获得紧凑的输出

我们可能希望去掉不必要的空格,这可以通过设置不同于默认: 的分隔符字符串来实现:

print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}

4: loadvs loads, dumpvs dumps

json 模块包含读写 unicode 字符串和读写文件的函数。这些函数以函数名后面的 s 来区分。在这些示例中,我们使用的是 StringIO 对象,但同样的函数也适用于任何类文件对象。

这里我们使用基于字符串的函数:

import json

data = {u"foo": u"bar", u"baz": []}
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}'
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}

在这里,我们使用基于文件的功能:

import json
from io import StringIO

json_file = StringIO()
data = {u"foo": u"bar", u"baz": []}
json.dump(data, json_file)
json_file.seek(0) # Seek back to the start of the file before reading
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0) # Seek back to the start of the file before reading
json.load(json_file)
# {u"foo": u"bar", u"baz": []}

正如你所看到的,主要区别在于转储 json 数据时必须将文件句柄传递给函数,而不是捕获返回值。另外值得注意的是,为了避免数据损坏,在读取或写入数据前,必须先找到文件的起始位置。打开文件时,光标位于位置 0,因此下面的方法也可以使用:

import json

json_file_path = './data.json'
data = {u"foo": u"bar", u"baz": []}

with open(json_file_path, 'w') as json_file:
  json.dump(data, json_file)
  
with open(json_file_path) as json_file:
  json_file_content = json_file.read()
  # u'{"foo": "bar", "baz": []}'

with open(json_file_path) as json_file:
  json.load(json_file)
  # {u"foo": u"bar", u"baz": []}

有了这两种处理 json 数据的方法,您就可以习惯性地、高效地使用基于 json 的格式,例如 pysparkjson-per-line

# loading from a file
data = [json.loads(line) for line in open(file_path).splitlines()]

# dumping to a file
with open(file_path, 'w') as json_file:
  for item in data:
    json.dump(item, json_file)
    json_file.write('\n')

记得要将上面代码中的 file_path 替换为实际的文件路径

5: 从命令行调用 json.tool以漂亮地打印 JSON 输出

给定某个 JSON 文件 "foo.json",如

{"foo": {"bar": {"baz": 1}}}

我们可以直接从命令行调用模块(将文件名作为参数传递)来漂亮打印:

$ python3 -m json.tool foo.json
{
  "foo": {
    "bar": {
      "baz": 1
    }
  }
}

该模块还将从 STDOUT 接收输入,因此(在 Bash 中)我们同样可以这样做:

$  cat foo.json | python3 -m json.tool

6: JSON 编码自定义对象

如果我们尝试以下方法

import json
from datetime import datetime
data = {'datetime': datetime(2024, 9, 26, 4, 44, 0)}
print(json.dumps(data))

我们会收到一个错误,提示 TypeError: Object of type datetime is not JSON serializable

为了能正确序列化 datetime 对象,我们需要编写自定义代码来转换它:

class DatetimeJSONEncoder(json.JSONEncoder):
  def default(self, obj):
    try:
      return obj.isoformat()
    except AttributeError:
      # obj 没有 isoformat 方法;让内置 JSON 编码器来处理吧
      return super(DatetimeJSONEncoder, self).default(obj)

然后使用该编码器类代替 json.dumps

encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2024-09-26T04:44:00"}

7: 从 Python dict 创建 JSON

import json
d = {
  'foo': 'bar',
  'alice': 1,
  'wonderland': [1, 2, 3]
}
json.dumps(d)

上述代码段将返回以下内容:

'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'

8: 从 JSON 创建 Python dict

import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)

上述代码段将返回以下内容:

{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/496.html

分享给朋友:

“python散装笔记——49: JSON 模块” 的相关文章

Linux发行版Debian推出12.2及11.8版本,修复多个安全问题

IT之家 10 月 9 日消息,Debian 是最古老的 GNU / Linux 发行版之一,也是许多其他基于 Linux 的操作系统的基础,包括 Ubuntu、Kali、MX 和树莓派 OS 等,近日 Debian 推出了 12.2 和 11.8 版本,主要修复了多个安全问题。▲ 图源 Debia...

vue 3 学习笔记 (八)——provide 和 inject 用法及原理

在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套...

多项修正 尼康D4s发布最新1.10版固件

尼康公司与2014年8月27日发布了D4s的最新固件,固件版本号为C:1.10。这次固件升级,主要解决了一些BUG,并且对拍摄菜单与相机操作做了一定调整。下面是本次新固件的具体信息:尼康发布D4s最新C固件 1.10版对C固件升级到1.10版所作的修改:当选定运动VR模式并换上 AF-S 尼克尔 4...

Vue学习笔记之动态路由的参数传递应用及技巧

路由的参数传递:①通过params的类型· 配置路由格式:/router/:id· 传递的方式:在path后面跟上对应的值· 传递后形成的路径:/router/list,/router/profile这个就是前两篇中提到的"动态路由"中有应用过这个方法:②通过query的类型(对象方...

Vue实现动态路由

通常我们在vue项目中都是前端配置好路由的,但在一些项目中我们可能会遇到权限控制,这样我们就涉及到动态路由的设置了。动态路由设置一般有两种:(1)、简单的角色路由设置: 比如只涉及到管理员和普通用户的权限。通常直接在前端进行简单的角色权限设置(2)、复杂的路由权限设置: 比如OA系统、多种角色的权限...

企业微信自建应用和消息发送配置对接系统指南

本文介绍企业微信应用创建、消息提醒、自动回复、自定义菜单和服务端接口对接过程。企业微信登录:https://work.weixin.qq.com/企业微信接口对接,应用授权和发送消息代码:https://www.easywechat.com/docs/5.x/wework/oauth一、创建自建应用...