Jsonifyする必要があるオブジェクトのリストがあります。 flask jsonify docsを見てきましたが、まだ理解できていません。
私のクラスには複数の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
をシリアル化する方法を伝える必要がありますが、クラスのインスタンスをシリアル化する方法を示す例を見つけることはできません。
このコードは動作します(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 __== '__main__':
app.run(debug=True)
Curlで呼び出すと、次のようになります:
{
"eqtls_by_gene": [
{
"gene_id": 1,
"gene_symbol": "EGFR",
"p_value": 0.1
},
{
"gene_id": 2,
"gene_symbol": "PTEN",
"p_value": 0.2
}
]
}
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)
_
json
モジュールのドキュメント を見ると、 サブクラスJSONEncoder
を使用してdefault
メソッドをオーバーライドし 、そこでタイプのサポートを追加します。オブジェクトを含む可能性のある複数の異なる構造をシリアル化する場合、これが最も一般的な処理方法になります。
jsonify
を使用する場合は、事前にオブジェクトを単純な型に変換する方が簡単です(たとえば、Martijnが提案するように、クラスで独自のメソッドを定義することにより)。