如何将 Python 数据结构中的所有小数转换为字符串?

Posted

技术标签:

【中文标题】如何将 Python 数据结构中的所有小数转换为字符串?【英文标题】:How to convert all Decimals in a Python data structure to string? 【发布时间】:2014-09-02 14:57:38 【问题描述】:

我正在使用Flask 构建一个网站,从中我经常使用 jsonify 方法将大部分字典转换为 Json。

现在的问题是我也经常使用小数,可惜jsonify不能处理小数:

jsonify('a': Decimal('1'))

导致:

=== (a long stacktrace preceding this) ===
File "/usr/local/lib/python2.7/dist-packages/flask/json.py", line 83, in default
return _json.JSONEncoder.default(self, o)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('1') is not JSON serializable

所以我想用这样的方法包装 jsonify:

def myOwnJsonify(item):
    if isinstance(item, Decimal):
        return flask.jsonify(str(item))
    else:
        return flask.jsonify(item)

不幸的是,这不会转换位于字典或列表中的小数。

如何将 python 数据结构(列表、字典、元组等)中的所有小数转换为字符串,以便我可以安全地将数据结构转换为 json?

【问题讨论】:

也许不是最好的方法,但你不能继承Decimal 并覆盖它的__repr__ 方法来得到你想要的吗? 【参考方案1】:

您可以通过在应用程序实例上设置 json_encoder 属性来覆盖应用程序的 JSON 编码器:

import flask

app = flask.Flask(...)
app.json_encoder = MyJSONEncoder

然后您可以继承 Flask 的 JSONEncoder 并覆盖 default() 方法以提供对其他类型的支持:

import decimal
import flask.json

class MyJSONEncoder(flask.json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            # Convert decimal instances to strings.
            return str(obj)
        return super(MyJSONEncoder, self).default(obj)

【讨论】:

这可能只是版本不同的问题,但我必须这样做 app.data.json_encoder_class = MyJSONEncoder 才能使其工作。 @hlongmore 我检查了最新版本的 Flask,1.1.1,它看起来仍在使用 Flask上的 json_encoder/decoder 属性> 类。我在Github repo 中没有看到 json_encoder_class 的提及。 我没有检查我的烧瓶版本;由于一些子包要求的问题,我现在没有时间整理(可能是由于 eve-sqlalchemy 远远落后于 eve),我不得不将 eve 固定到

以上是关于如何将 Python 数据结构中的所有小数转换为字符串?的主要内容,如果未能解决你的问题,请参考以下文章

python之struct详解

Python之struct

Python struct模块

如何在不丢失小数的情况下将数据框中的字符转换为数字

struct&optparse模块

Python做int()强制类型转换的时候,小数是如何取舍的?