Python Flask jsonify 对象列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21411497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Flask jsonify a list of objects
提问by Jared Nedzel
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.
我有一个需要 jsonify 的对象列表。我看过烧瓶 jsonify 文档,但我只是不明白。
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?
我的班级有几个 inst-vars,每个都是一个字符串:gene_id, gene_symbol, p_value。我需要做什么才能将此序列化为 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.
大概我必须告诉 jsonify 如何序列化一个EqtlByGene,但我找不到显示如何序列化类实例的示例。
This code now works (with many thanks to Martijn Pieters!):
这段代码现在可以工作了(非常感谢 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:
当我通过 curl 调用它时,我得到:
{
"eqtls_by_gene": [
{
"gene_id": 1,
"gene_symbol": "EGFR",
"p_value": 0.1
},
{
"gene_id": 2,
"gene_symbol": "PTEN",
"p_value": 0.2
}
]
}
采纳答案by Martijn Pieters
Give your EqltByGenean extra method that returns a dictionary:
给你EqltByGene一个额外的方法来返回一个字典:
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.
另一种方法是为该json.dumps()函数编写一个钩子函数,但由于您的结构相当简单,列表理解和自定义方法方法更简单。
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:
你也可以是真正的冒险家和子类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)
and assign this to the app.json_encoderattribute:
并将其分配给app.json_encoder属性:
app = Flask(__name__)
app.json_encoder = MyJSONEncoder
and just pass in your list directly to jsonify():
并将您的列表直接传递给jsonify():
return jsonify(my_list_of_eqtls)
回答by Amber
If you look at the docs for the jsonmodule, it mentions that you can subclass JSONEncoderto override its defaultmethodand add support for types there. That would be the most generic way to handle it if you're going to be serializing multiple different structures that might contain your objects.
如果您查看模块的文档json,它会提到您可以子类化JSONEncoder以覆盖其default方法并在那里添加对类型的支持。如果您要序列化可能包含您的对象的多个不同结构,那将是最通用的处理方式。
If you want to use jsonify, it's probably easier to convert your objects to simple types ahead of time (e.g. by defining your own method on the class, as Martijn suggests).
如果您想使用jsonify,提前将您的对象转换为简单类型可能更容易(例如,通过在类上定义您自己的方法,正如 Martijn 建议的那样)。

