2

次のPythonコードのブロックがあります。

data = json.loads(line)
if data.has_key('derivedFrom'):
     dFin = data['derivedFrom']
     if dFin.has_key('derivedIds'):

これは、次のようなJSONのブロックで正常に機能していました。

"derivedFrom": {"source": "FOO", "model": "BAR", "derivedIds": ["123456"]}

これで、形式が次のように変更されました。

"derivedFrom": "{\"source\": \"FOO.\", \"model\": \"BAR\", \"derivedIds\": [\"123456\"]

したがって、Pythonブロックの最後の行は、次の例外をスローします。

'unicode' object has no attribute 'has_key'

has_keyJSONを前処理して再び機能させる方法はありますか?

4

4 に答える 4

10
"{\"source\": \"FOO.\", \"model\": ...

JSON文字列リテラル内のJSONオブジェクトです。内部JSONのプロパティを取得するには、それを再度デコードする必要があります。

data = json.loads(line)
if 'derivedFrom' in data:
    dFin = json.loads(data['derivedFrom'])
    if 'derivedIds' in dFin:
        ....

JSON-in-JSONは、必要になることはめったにないため、通常は間違いです。この出力を生成しているのは何ですか、修正する必要がありますか?

于 2012-12-20T22:35:00.100 に答える
1

使用する:

'derivedIds' in dFin

これは辞書とUnicodeの両方で機能しますが、Unicodeでは誤検知が発生する可能性があります。

より堅牢なアプローチでは、ダックタイピングを使用できます。

try:
    dFin = json.loads(data['derivedFrom'])  #assume new format
except TypeError:
    dFin = data['derivedFrom']  #it's already a dict
if 'derivedIds' in dFin: # or dFin.has_key('derivedIds')
    #etc
于 2012-12-20T18:11:59.093 に答える
0

派生元プロパティをJSONオブジェクトから文字列に変更しています。文字列には、has_keyという名前の属性はありません。

于 2012-12-20T16:11:46.573 に答える
0

まったく同じコードブロックを機能させたい場合は、新しいフォーマットを次のように少し調整することを検討してください。

"{\"derivedFrom\": {\"source\": \"FOO.\", \"model\": \"BAR\", \"derivedIds\": [\"123456\"]}}"
于 2012-12-20T18:46:09.973 に答える