2

ここでは、いくつかの JSON (形式を変更できません。これは私が作成したサービスではありません) を Python オブジェクトに逆シリアル化するための簡単な問題に取り組んでいます。json.loadsラムダを使用して変換を行うことができましたが、メソッドを使用して変換を行うことが可能かどうかを確認するために、今 object_hook を使用したいと思います。しかし、それは私が今失敗しているところであり、誰かが私を正しい方向に向けることができるかどうか疑問に思っていました.

これは私が現在持っているコードです:

import json

class Light:
    def __init__(self, id, name):
        self.id = id
        self.name = name

response = '{"1": {"name": "bedroom"}, "2": {"name": "kitchen"}}'

def object_decoder(obj):
    return Light(......)

print json.loads(response, object_hook=object_decoder)

ご覧のとおり、responseは 1 と 2 という名前の 2 つのキーを持つ 1 つのドキュメントです。 が 2 つの Light オブジェクトを返すようにコードを動作させることができればいいのですjson.loadsが、現時点では行き詰まっています。 、そしてこれを機能させるために応答を反復する方法がわかりません。

4

2 に答える 2

6

object_hookjson 文字列のさまざまなレベルにidとがあるため、役に立ちません。name

object_hook が指定されている場合、デコードされたすべての JSON オブジェクトの結果とともに呼び出され、その戻り値が指定された dict の代わりに使用されます。

なぜ役に立たないのか見てみましょうobject_hook。関数に到達するオブジェクトを出力するとobject_decoder、次のように深いところから上昇していることがわかります。

{u'name': u'bedroom'}
{u'name': u'kitchen'}
{u'1': None, u'2': None}
None

これは、インスタンスobject_decoderを生成するために呼び出しに参加できないことを意味します。Light

代わりにカスタムJSONDecoderクラスを使用するのはどうですか:

import json


class Light:
    def __init__(self, id, name):
        self.id = id
        self.name = name


response = '{"1": {"name": "bedroom"}, "2": {"name": "kitchen"}}'


class Decoder(json.JSONDecoder):
    def decode(self, s):
        obj = super(Decoder, self).decode(s)
        return [Light(id=k, name=v['name']) for k, v in obj.iteritems()]


lights = json.loads(response, cls=Decoder)
print lights  # prints [<__main__.Light instance at 0x9c3b50c>, <__main__.Light instance at 0x9c3b56c>]
print [light.__dict__ for light in lights]  # prints [{'id': u'1', 'name': u'bedroom'}, {'id': u'2', 'name': u'kitchen'}]

json.loads()これは実際には、クラスを作成してからインスタンス化することと同じです。

于 2013-09-02T20:06:40.780 に答える