一尘不染

Flask jsonify对象列表

json

我有一个需要jsonify的对象列表。我看了烧瓶jsonify文档,但我只是不明白。

我班有几个研究所,增值经销商,每一个都是一个字符串:gene_idgene_symbolp_value。我需要怎么做才能将此序列化为JSON?

我的天真代码:

jsonify(eqtls = my_list_of_eqtls)

结果是:

TypeError: <__main__.EqtlByGene object at 0x1073ff790> is not JSON serializable

大概我必须告诉jsonify如何序列化EqtlByGene,但是我找不到一个显示如何序列化类实例的示例。

我一直在尝试遵循下面显示的一些建议来创建自己的JSONEncoder子类。我的代码现在是:

class EqtlByGene(Resource):

    def __init__(self, gene_id, gene_symbol, p_value):
        self.gene_id = gene_id
        self.gene_symbol = gene_symbol
        self.p_value = p_value

class EqtlJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, EqtlByGene):
            return {
                   'gene_id'     : obj.gene_id,
                   'gene_symbol' : obj.gene_symbol,
                   'p_value'     : obj.p_value
            }
        return super(EqtlJSONEncoder, self).default(obj)

class EqtlByGeneList(Resource):
    def get(self):
        eqtl1 = EqtlByGene(1, 'EGFR', 0.1)
        eqtl2 = EqtlByGene(2, 'PTEN', 0.2)
        eqtls = [eqtl1, eqtl2]
        return jsonify(eqtls_by_gene = eqtls)

api.add_resource(EqtlByGeneList, '/eqtl/eqtlsbygene')
app.json_encoder(EqtlJSONEncoder)
if __name__ == '__main__':
    app.run(debug=True)

当我尝试通过卷曲达到它时,我得到:

TypeError(repr(o) + " is not JSON serializable")

阅读 296

收藏
2020-07-27

共1个答案

一尘不染

给您EqltByGene一个额外的方法来返回字典:

class EqltByGene(object):
    #

    def serialize(self):
        return {
            'gene_id': self.gene_id, 
            'gene_symbol': self.gene_symbol,
            'p_value': self.p_value,
        }

然后使用列表推导将您的对象列表转换为可序列化值的列表:

jsonify(eqtls=[e.serialize() for e in my_list_of_eqtls])

另一种方法是为该json.dumps()函数编写一个钩子函数,但是由于您的结构很简单,因此列表理解和自定义方法更简单。

您也可以冒险和继承类别flask.json.JSONEncoder;
给它一个default()EqltByGene()实例转换为可序列化值的方法:

from flask.json import JSONEncoder

class MyJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, EqltByGene):
            return {
                'gene_id': obj.gene_id, 
                'gene_symbol': obj.gene_symbol,
                'p_value': obj.p_value,
            }
        return super(MyJSONEncoder, self).default(obj)

并将其分配给app.json_encoder属性

app = Flask(__name__)
app.json_encoder = MyJSONEncoder

并将您的列表直接传递给jsonify()

return jsonify(my_list_of_eqtls)

您还可以在Marshmallow项目中找到一个更全面,更灵活的项目,该项目用于将对象序列化和反序列化为易于适合JSON和其他此类格式的Python原语;例如:

from marshmallow import Schema, fields

class EqltByGeneSchema(Schema):
    gene_id = fields.Integer()
    gene_symbol = fields.String()
    p_value = fields.Float()

然后使用

jsonify(eqlts=EqltByGeneSchema().dump(my_list_of_eqtls, many=True)

产生JSON输出。可以使用相同的架构来验证传入的JSON数据,并(使用适当的额外方法)可以用于EqltByGene再次产生实例。

2020-07-27