[英]Flask jsonify a list of objects
我有一個需要 jsonify 的對象列表。 我看過燒瓶 jsonify 文檔,但我只是不明白。
我的班級有幾個 inst-var,每個都是一個字符串: gene_id
、 gene_symbol
、 p_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)
當我嘗試通過 curl 到達它時,我得到:
TypeError(repr(o) + " is not JSON serializable")
為您的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 項目以獲得更成熟和靈活的項目,用於將對象序列化和反序列化為 Python 原語,可輕松適應 JSON 和其他此類格式; 例如:
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
實例。
如果您查看json
模塊的文檔,它會提到您可以JSONEncoder
以覆蓋其default
方法並在那里添加對類型的支持。 如果您要序列化可能包含您的對象的多個不同結構,那將是最通用的處理方式。
如果您想使用jsonify
,提前將您的對象轉換為簡單類型可能更容易(例如,通過在類上定義您自己的方法,正如 Martijn 建議的那樣)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.