Flask对对象列表进行分组 [英] Flask jsonify a list of objects

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

问题描述

我有一个需要对象化的对象列表。我已经看了瓶子jsonify文档,但我只是没有得到它。

我的类有几个inst-vars,其中每个是一个字符串: gene_id gene_symbol p_value 。我需要做什么才能使这个序列化为JSON?

我的天真代码:

  jsonify(eqtls = my_list_of_eqtls)

结果:

  TypeError:< __ main __。EqtlByGene object at 0x1073ff790>不是JSON序列化

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



这个代码现在可以工作了(非常感谢(Martijn Pieters!):

pre $ class $ E $ $ $ $ $ $ $ $ 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):
如果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]
返回jsonify(eqtls_by_gene = eqtls)

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

当我通过curl调用它时, :

$ $ $
$ e $ $ $ $ $ $ $ $ $ $ $ $ $ $ $'
gene_symbol:EGFR,
p_value:0.1
},
{
gene_id:2,
gene_symbol: PTEN,
p_value:0.2
}
]
}


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

  class EqltByGene(object):


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

然后使用list comprehension将对象列表转换为可序列化的值列表:

<$ p
$ jsonify(eqtls = [e.serialize()for my_list_of_eqtls])

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

你也可以真正喜欢冒险和子类 flask.json.JSONEncoder ;给它一个 default()方法,将 EqltByGene()实例转换为一个可序列化的值:

  from flask.json import JSONEncoder 
$ b class MyJSONEncoder(JSONEncoder):
def default(self,obj) :
如果isinstance(obj,EqltByGene):
返回{
'gene_id':obj.gene_id,
'gene_symbol':obj.gene_symbol,
'p_value' :obj.p_value,
}
return super(MyJSONEncoder,self).default(obj)

并将其分配给 应用程序。 json_encoder 属性

  app = Flask(__ name__)
app。 json_encoder = MyJSONEncoder

直接传递给 jsonify() / code>:

  return jsonify(my_list_of_eqtls)


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.

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?

My naive code:

jsonify(eqtls = my_list_of_eqtls)

Results in:

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

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.

This code now works (with many thanks to Martijn Pieters!):

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)

When I call it via curl, I get:

{
  "eqtls_by_gene": [
    {
      "gene_id": 1, 
      "gene_symbol": "EGFR", 
      "p_value": 0.1
    }, 
    {
      "gene_id": 2, 
      "gene_symbol": "PTEN", 
      "p_value": 0.2
    }
  ]
}

解决方案

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])

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.

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)

and assign this to the app.json_encoder attribute:

app = Flask(__name__)
app.json_encoder = MyJSONEncoder

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

return jsonify(my_list_of_eqtls)

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

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