Python JSON编码器支持日期时间?
有没有什么优雅的方法可以让 Python JSON 编码器支持日期时间?一些第 3 方模块或简单的 hack?
is there any elegant way to make Python JSON encoder support datetime? some 3rd party module or easy hack?
我正在使用 tornado 的数据库包装器从 db 中获取一些行以生成 json.查询结果包含一个常规的 MySQL 时间戳列.
I am using tornado's database wrapper to fetch some rows from db to generate a json. The query result includes a regular MySQL timestamp column.
很烦人的是 Python 的默认 json 编码器不支持它自己的 datetime 类型,这在各种数据库查询中都很常见.
It's quite annoying that Python's default json encoder doesn't support its own datetime type, which is so common in all kinds of database queries.
我不想修改 Python 自己的 json 编码器.有什么好的做法吗?非常感谢!
I don't want to modify Python's own json encoder. any good practice? Thanks a lot!
ps:我通过修改 Python JSON 编码器默认方法发现了一个肮脏的 hack:
ps: I found a dirty hack by modifying the Python JSON encoder default method:
变化:
def default(self, o):
raise TypeError(repr(o) + " is not JSON serializable")
收件人:
def default(self, o):
from datetime import date
from datetime import datetime
if isinstance(o, datetime):
return o.isoformat()
elif isinstance(o, date):
return o.isoformat()
else:
raise TypeError(repr(o) + " is not JSON serializable")
好吧,这将是仅适用于开发环境的临时解决方案.
well, it will be a temporary solution just for dev environment.
但是对于长期的解决方案或生产环境,这很丑陋,每次部署到新服务器时都必须进行修改.
But for long term solution or production environment, this is quite ugly, and I have to do the modification every time I deploy to a new server.
有没有更好的方法?我不想修改 Python 代码本身,也不想修改 Tornado 源代码.我可以用我自己的项目代码做些什么来实现这一点吗?最好是一步到位.
Is there a better way? I do not want to modify Python code itself, neither Tornado source code. Is there something I can do with my own project code to make this happen? preferably in one pace.
非常感谢!
推荐答案
文档建议继承 JSONEncoder 并实现您自己的默认方法.好像你基本上在那里,而且它不是一个肮脏的黑客".
The docs suggest subclassing JSONEncoder and implementing your own default method. Seems like you're basically there, and it's not a "dirty hack".
默认编码器不处理日期的原因是 JSON 中没有标准的日期表示.有些人使用的是/Date(1198908717056)/
,不过我个人更喜欢ISO格式.
The reason dates aren't handled by the default encoder is there is no standard representation of a date in JSON. Some people are using the format /Date(1198908717056)/
, but I prefer ISO format personally.
import json
import datetime
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime.datetime, datetime.date, datetime.time)):
return obj.isoformat()
elif isinstance(obj, datetime.timedelta):
return (datetime.datetime.min + obj).time().isoformat()
return super(DateTimeEncoder, self).default(obj)
now = datetime.datetime.now()
encoder = DateTimeEncoder()
encoder.encode({"datetime": now, "date": now.date(), "time": now.time()})
> {"datetime": "2019-07-02T16:17:09.990126", "date": "2019-07-02", "time": "16:17:09.990126"}
相关文章