类型错误:日期时间类型的对象不是 JSON 可序列化的

目录

TypeError: Object of type datetime is not JSON serializable

  1. 类型错误:日期时间类型的对象不是 JSON 可序列化的
  2. 类型错误:时间戳类型的对象不是 JSON 可序列化的

TypeError: 日期时间类型的对象不是 JSON 可序列化的

datetime当我们尝试将对象转换为 JSON 字符串时,会出现 Python“TypeError: Object of type datetime is not JSON serializable” 。

要解决该错误,请在对该方法的调用中将default关键字参数设置为strjson.dumps()

下面是错误如何发生的示例。

主程序
import json from datetime import datetime now = datetime.now() # ⛔️ TypeError: Object of type datetime is not JSON serializable json_str = json.dumps({'created_at': now}, default=str)

我们尝试将datetime对象传递给该json.dumps()方法,但默认情况下该方法不处理datetime对象。

提供default关键字参数来解决错误

要解决错误,请将default设置它的关键字参数传递给str
类。

主程序
import json from datetime import datetime now = datetime.now() # ✅ set default=str json_str = json.dumps({'created_at': now}, default=str) print(json_str) # 👉️ '{"created_at": "2023-02-09 08:55:42.713290"}' print(type(json_str)) # 👉️ <class 'str'>

json.dumps方法将 Python 对象转换为 JSON 格式字符串。

关键字default参数可以设置为为无法序列化的对象调用的函数。

我们只需将datetime对象传递给类即可将其转换为字符串str

定义自定义 JSON 序列化器函数

您还可以定义一个自定义 JSON 序列化程序函数,负责将日期转换为 JSON。

主程序
from datetime import date, datetime import json def json_serializer(obj): if isinstance(obj, (datetime, date)): return obj.isoformat() raise TypeError(f'Type {type(obj)} is not serializable') now = datetime.now() json_str = json.dumps({'created_at': now}, default=json_serializer) # 👇️ {"created_at": "2023-02-09T09:11:35.002192"} print(json_str)

请注意,我们将default关键字参数设置为json_serializer
函数而不是
str类。

该函数
检查提供的值是否为日期时间
date对象,如果满足条件,它使用
date.toisoformat
方法返回表示 ISO 8601 格式的日期和时间的字符串。

主程序
from datetime import datetime now = datetime.now() # 👇️ 2023-02-09T09:14:19.515138 print(now.isoformat())

如果传递给函数的值不是日期对象,则TypeError
引发 a。

创建一个自定义DTEncoder类来解决错误

另一种方法是从类扩展JSONEncoder并只对对象进行转换datetime

主程序
import json from datetime import datetime class DTEncoder(json.JSONEncoder): def default(self, obj): # 👇️ if passed in object is datetime object # convert it to a string if isinstance(obj, datetime): return str(obj) # 👇️ otherwise use the default behavior return json.JSONEncoder.default(self, obj) now = datetime.now() json_str = json.dumps({'created_at': now}, cls=DTEncoder) print(json_str) # 👉️ '{"created_at": "2022-05-22 16:21:25.460716"}' print(type(json_str)) # 👉️ <class 'str'>

我们从
JSONEncoder
类扩展而来。

该类JSONEncoder默认支持以下对象和类型。

Python JSON
字典 目的
列表,元组 大批
海峡 细绳
int、float、int 和 float 派生枚举 数字
真的 真的
错误的 错误的
没有任何 无效的

请注意,该类默认JSONEncoder不支持对象到 JSON 的转换。datetime

我们可以通过从类扩展并实现一个default()
返回可序列化对象的方法来处理这个问题。

主程序
import json from datetime import datetime class DTEncoder(json.JSONEncoder): def default(self, obj): # 👇️ if passed in object is datetime object # convert it to a string if isinstance(obj, datetime): return str(obj) # 👇️ otherwise use the default behavior return json.JSONEncoder.default(self, obj)
在我们的if语句中,我们检查传入的对象是否是该类的实例datetime,如果是,我们将其转换为字符串并返回结果。

在所有其他情况下,我们让基类的默认方法进行序列化。

要使用自定义,请在调用该方法时JSONEncoder使用关键字参数指定它clsjson.dumps()

主程序
# ✅ pass cls keyword argument json_str = json.dumps({'created_at': now}, cls=DTEncoder)

如果您不提供clskwarg,JSONEncoder则使用默认值。

使用strftime()方法解决错误

您还可以使用该strftime方法将datetime对象转换为字符串,然后再将其转换为 JSON。

主程序
import datetime import json now = datetime.datetime.now() a_str = now.strftime('%Y-%m-%d %H:%M:%S') print(a_str) # 👉️ 2023-02-09 09:20:00 json_str = json.dumps(a_str) print(json_str) # 👉️ "2023-02-09 09:20:00"

该类datetime有一个
strftime
方法,我们可以使用它来获取日期和时间的字符串表示形式,由显式格式字符串控制。

代码示例将datetime对象格式化为YYYY-MM-DD HH:MM:SS.

您还可以在结果中包含毫秒数。

主程序
import datetime import json now = datetime.datetime.now() a_str = now.strftime('%Y-%m-%d %H:%M:%S.%f') print(a_str) # 👉️ 2023-02-09 09:21:44.753545 json_str = json.dumps(a_str) print(json_str) # 👉️ "2023-02-09 09:21:44.753545"

如果您想datetime以不同的方式格式化字符串,请使用
此文档表
来查找您应该作为第二个参数传递给该
strftime()方法的格式代码。

str()转换时使用类

将值转换为 JSON 时,您还可以使用str()类。

主程序
import json from datetime import datetime now = datetime.utcnow() json_str = json.dumps({'created_at': str(now)}) # 👇️ {"created_at": "2023-02-09 07:05:57.075261"} print(json_str)

我们不依赖default关键字参数,而是使用类将日期显式转换为字符串str()

TypeError: Timestamp 类型的对象不是 JSON 可序列化的

当我们尝试将对象转换为 JSON 字符串时,会出现 Python“TypeError: Object of type Timestamp is not JSON serializable” Timestamp

要解决该错误,请先将Timestamp对象转换为,str然后再将其序列化为 JSON。

下面是错误如何发生的示例。

主程序
import json import pandas as pd tstamp = pd.Timestamp('2023-01-01T12') # ⛔️ TypeError: Object of type Timestamp is not JSON serializable json_str = json.dumps({'created_at': tstamp})

我们尝试将Timestamp对象传递给该json.dumps()方法,但默认情况下该方法不处理Timestamp对象

将 the 转换Timestamp为 astr以解决错误

要解决该错误,请在序列化之前使用内置str()类将其转换Timestamp
str

主程序
import json import pandas as pd tstamp = pd.Timestamp('2023-01-01T12') # ✅ convert to str json_str = json.dumps({'created_at': str(tstamp)}) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>

默认的 JSON 编码器处理值,因此我们可以在序列化为 JSON 时str使用本机 Python
str而不是Python。Timestamp

json.dumps方法将 Python 对象转换为 JSON 格式字符串。

创建一个自定义PdEncoder类来解决错误

或者,您可以从JSONEncoder类扩展并在方法中处理转换default

主程序
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj) tstamp = pd.Timestamp('2023-01-01T12') json_str = json.dumps({'created_at': tstamp}, cls=PdEncoder) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>

我们从
JSONEncoder
类扩展而来。

该类JSONEncoder默认支持以下对象和类型。

Python JSON
字典 目的
列表,元组 大批
海峡 细绳
int、float、int 和 float 派生枚举 数字
真的 真的
错误的 错误的
没有任何 无效的

请注意,该类默认JSONEncoder不支持JSON 转换。Timestamp

我们可以通过从类扩展并实现一个default()
返回可序列化对象的方法来处理这个问题。

主程序
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj)

如果传入的值是 a Timestamp,我们将其转换为 astr并返回结果。

如果传入的对象是传入类的实例或子类,则isinstance函数返回
True

在所有其他情况下,我们让基类的默认方法进行序列化。

要使用自定义,请在调用该方法时JSONEncoder使用关键字参数指定它clsjson.dumps()

主程序
import json import pandas as pd class PdEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return str(obj) return json.JSONEncoder.default(self, obj) tstamp = pd.Timestamp('2023-01-01T12') json_str = json.dumps({'created_at': tstamp}, cls=PdEncoder) print(json_str) # 👉️ '{"created_at": "2023-01-01 12:00:00"} print(type(json_str)) # 👉️ <class 'str'>

如果您不提供clskwarg,JSONEncoder则使用默认值。

我还写了一篇关于
如何检查变量是否为 Datetime 对象的文章。

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: