json.dumps 使用科学记数法输出小浮点或十进制值,这对于将此输出发送到的 json-rpc 应用程序来说是 Not Acceptable 。
>>> import json
>>> json.dumps({"x": 0.0000001})
'{"x": 1e-07}'
我想要这个输出:
'{"x": 0.0000001}'
最好避免引入额外的依赖项。
最佳答案
一种格式化方法
evil = {"x": 0.00000000001}
是窃取Decimal
的“f”格式化程序。这是我发现的唯一可以避免裁剪问题和指数的简单方法,但它不节省空间。
class FancyFloat(float):
def __repr__(self):
return format(Decimal(self), "f")
要使用它,您可以制作一个对输入进行“十进制化”的编码器
class JsonRpcEncoder(json.JSONEncoder):
def decimalize(self, val):
if isinstance(val, dict):
return {k:self.decimalize(v) for k,v in val.items()}
if isinstance(val, (list, tuple)):
return type(val)(self.decimalize(v) for v in val)
if isinstance(val, float):
return FancyFloat(val)
return val
def encode(self, val):
return super().encode(self.decimalize(val))
JsonRpcEncoder().encode(evil)
#>>> '{"x": 0.00000000000999999999999999939496969281939810930172340963650867706746794283390045166015625}'
或者,当然,您可以将十进制移出到一个函数中,并在 json.dumps
之前调用它。
我就是这么做的,即使这是一个蹩脚的方法。
<小时/>更新
Sam Mason 建议改用 format(Decimal(str(self)), "f")
,它仍应始终往返,但也会产生较短的输出。
关于python - 在 python json.dumps 输出中禁用科学记数法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18936554/