Mak*_*cha 5 python datetime json bson bottle
当我尝试返回包含datetime值的 JSON 时,我得到
File "/usr/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2014, 2, 1, 0, 0) is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
这是正常的。有没有一种简单的方法来添加对象bottle钩子
from bson import json_util
import json
json.dumps(anObject, default=json_util.default)
Run Code Online (Sandbox Code Playgroud)
获得datetime转换值?
有趣的问题!我可以看到有几种方法可以做到这一点。一种是编写一个自定义插件来包装JSONPlugin:
from bottle import route, run, install, JSONPlugin
from bson import json_util
class JSONDefaultPlugin(JSONPlugin):
def __init__(self):
super(JSONDefaultPlugin, self).__init__()
self.plain_dump = self.json_dumps
self.json_dumps = lambda body: self.plain_dump(body, default=json_util.default)
Run Code Online (Sandbox Code Playgroud)
然后可以这样使用:
@route('/hello')
def index(name):
return {'test': datetime.datetime(2014, 2, 1, 0, 0)}
install(JSONDefaultPlugin())
run(host='localhost', port=8080)
Run Code Online (Sandbox Code Playgroud)
并会给出这样的输出:
{"test": {"$date": 1391212800000}}
Run Code Online (Sandbox Code Playgroud)
json_loads另一种更简短的方法是在实例化 JSONPlugin 类时简单地指定参数:
import json
from bson import json_util
install(JSONPlugin(json_dumps=lambda body: json.dumps(body, default=json_util.default)))
Run Code Online (Sandbox Code Playgroud)
这会产生相同的结果。
当您查看Bottle 的源代码时,这一切都更有意义(为简洁起见,下面删除了一些部分):
class JSONPlugin(object):
name = 'json'
api = 2
def __init__(self, json_dumps=json_dumps):
self.json_dumps = json_dumps
def apply(self, callback, route):
dumps = self.json_dumps
if not dumps: return callback
def wrapper(*a, **ka):
...
if isinstance(rv, dict):
...
elif isinstance(rv, HTTPResponse) and isinstance(rv.body, dict):
rv.body = dumps(rv.body)
rv.content_type = 'application/json'
return rv
return wrapper
Run Code Online (Sandbox Code Playgroud)
我们需要做的就是确保对dumps那里的调用接收到default您希望提供的关键字参数。
| 归档时间: |
|
| 查看次数: |
1602 次 |
| 最近记录: |