在 python json.dumps 输出中禁用科学记数法

Dus*_*ust 10 python json scientific-notation

json.dumps 使用科学记数法输出小的浮点数或十进制值,这对于将此输出发送到的 json-rpc 应用程序是不可接受的。

>>> import json
>>> json.dumps({"x": 0.0000001})
'{"x": 1e-07}'
Run Code Online (Sandbox Code Playgroud)

我想要这个输出:

'{"x": 0.0000001}'
Run Code Online (Sandbox Code Playgroud)

最好避免引入额外的依赖项。

Vee*_*rac 5

一种格式化方式

evil = {"x": 0.00000000001}
Run Code Online (Sandbox Code Playgroud)

是窃取Decimal“f”格式化程序。这是我发现避免裁剪问题和指数的唯一简单方法,但它不节省空间

class FancyFloat(float):
    def __repr__(self):
        return format(Decimal(self), "f")
Run Code Online (Sandbox Code Playgroud)

要使用它,您可以制作一个“十进制”输入的编码器

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}'
Run Code Online (Sandbox Code Playgroud)

或者,当然,您可以将十进制移出到一个函数中并在json.dumps.

这就是我要做的,即使这是一种蹩脚的方法。