【发布时间】:2015-04-24 12:46:48
【问题描述】:
编辑:使用
添加新输出logging.info(id(type(Decimal(10))))
logging.info(id(type(obj)))
我正在尝试转储到 JSON。我知道我需要将 Decimal 转换为浮点数,所以这是我的代码:
def get(self):
results = CheckPulseRequest.get(get_args(self.request))
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps(results, cls=DateTimeEncoder))
然后我定义了 DateTimeEncoder 如下:
class DateTimeEncoder(json.JSONEncoder):
logging.info("In DateTimeEncoder Class")
def default(self, obj):
logging.info(id(type(Decimal(10))))
logging.info(id(type(obj)))
logging.info(type(Decimal(10)))
logging.info(type(obj))
logging.info(isinstance(Decimal(10), (int, long, float, complex, Decimal)))
logging.info(isinstance(obj, (int, long, float, complex, Decimal)))
if isinstance(obj, Decimal):
logging.info("Is Instance of Decimal")
return float(obj)
elif hasattr(obj, 'isoformat'):
logging.info("Is ISO Format")
return obj.isoformat()
else:
logging.info("Else")
return json.JSONEncoder.default(self, obj)
我得到以下日志输出。我的十进制对象不会转换为浮点数。请注意,该对象与 Decimal 具有相同的类型,但 isinstance 测试仅在 Decimal(10) 测试中为 True。我错过了什么?
INFO 2015-02-23 18:49:45,737 check_pulse_request.py:25] Getting Check Pulse Request ID: 4
INFO 2015-02-23 18:49:46,374 main.py:179] 140647859901984
INFO 2015-02-23 18:49:46,375 main.py:180] 140647856664608
INFO 2015-02-23 18:49:46,375 main.py:181] <class 'decimal.Decimal'>
INFO 2015-02-23 18:49:46,375 main.py:182] <class 'decimal.Decimal'>
INFO 2015-02-23 18:49:46,375 main.py:183] True
INFO 2015-02-23 18:49:46,375 main.py:184] False
INFO 2015-02-23 18:49:46,376 main.py:193] Else
ERROR 2015-02-23 18:49:46,376 webapp2.py:1552] Decimal('-122.39906660000000') is not JSON serializable
Traceback (most recent call last):
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/Users/sheridangray/Projects/adt-bundle-mac-x86_64-20140702/sdk/google-cloud-sdk/platform/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/Users/sheridangray/Projects/city-pulse-appengine/city-pulse/main.py", line 38, in get
self.response.out.write(json.dumps(results, cls=DateTimeEncoder))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/Users/sheridangray/Projects/city-pulse-appengine/city-pulse/main.py", line 194, in default
return json.JSONEncoder.default(self, obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('-122.39906660000000') is not JSON serializable
【问题讨论】:
-
您的代码中没有任何其他名为
Decimal的类吗? -
Hrm,不知道为什么这被否决了。有代码,有错误信息,有什么不喜欢的?当然,错误看起来不协调,但显然这里存在类型不匹配,因为
type(obj)使它看起来 像decimal.Decimal()实例。我只是不确定default代码中的Decimal是否与传入的类相同。两个不同的decimal.Decimal类可以解释错误。 -
您能否将
id(Decimal)和id(type(obj))的日志记录添加到您的代码中并重新运行? -
我会小心地将小数序列化为浮点数,因为你可能会失去精度——因为浮点数只有一组有限的值,而 Decimal 的值是无限的。仅当您的值具有 20 个或更多有效数字时,这才真正重要。考虑使用
simplejson使用simplejson.dumps(obj, use_decimal=True)。 -
@Dunes:所有
simplejson所做的都是使用str(Decimal)。 OP 可以在这里简单地做同样的事情。
标签: python json serialization