Flask jsonify 对象列表 [英] Flask jsonify a list of objects

查看:51
本文介绍了Flask jsonify 对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a list of objects that I need to jsonify. I've looked at the flask jsonify docs, but I'm just not getting it.

我的班级有几个inst-var,每个都是一个字符串:gene_idgene_symbolp_value.我需要做什么才能将此序列化为 JSON?

My class has several inst-vars, each of which is a string: gene_id, gene_symbol, p_value. What do I need to do to make this serializable as JSON?

我的天真代码:

jsonify(eqtls = my_list_of_eqtls)

结果:

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

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

Presumably I have to tell jsonify how to serialize an EqtlByGene, but I can't find an example that shows how to serialize an instance of a class.

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

I've been trying to follow some of the suggestions show below to create my own JSONEncoder subclass. My code is now:

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)

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

When I try to reach it via curl, I get:

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

推荐答案

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

Give your EqltByGene an extra method that returns a dictionary:

class EqltByGene(object):
    #

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

然后使用列表理解将对象列表转换为可序列化值列表:

then use a list comprehension to turn your list of objects into a list of serializable values:

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

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

The alternative would be to write a hook function for the json.dumps() function, but since your structure is rather simple, the list comprehension and custom method approach is simpler.

你也可以非常喜欢冒险和子类flask.json.JSONEncoder;给它一个 default() 方法,把你的 EqltByGene() 实例变成一个可序列化的值:

You can also be really adventurous and subclass flask.json.JSONEncoder; give it a default() method that turns your EqltByGene() instances into a serializable value:

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属性:

and assign this to the app.json_encoder attribute:

app = Flask(__name__)
app.json_encoder = MyJSONEncoder

然后将您的列表直接传递给 jsonify():

and just pass in your list directly to jsonify():

return jsonify(my_list_of_eqtls)

您还可以查看 Marshmallow 项目 以获得更成熟和灵活的项目用于将对象序列化和反序列化为易于适应 JSON 和其他此类格式的 Python 原语;例如:

You could also look at the Marshmallow project for a more full-fledged and flexible project for serializing and de-serializing objects to Python primitives that easily fit JSON and other such formats; e.g.:

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 实例.

to produce JSON output. The same schema can be used to validate incoming JSON data and (with the appropriate extra methods), used to produce EqltByGene instances again.

这篇关于Flask jsonify 对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆