2013-04-16 84 views
1

我絕不是Python大師,但我知道我的方式。在過去的兩個小時,但我一直在對我的頭撞針對:就地編輯Python字典或解析json到對象

我解析從WCF Webservice使用json.loads()函數的JSON響應。結果是我在整個應用程序中使用的Python字典。但是,現在我需要混淆id,reseller_id等以用於HTTP GET請求。

這是例如響應:(注意,我有很多這樣的答覆,所以我要尋找一個通用的解決方案。)我想的散列替換任何id的值值

{ 
    "token":"String content", 
    "user":{ 
     "distributor":{ 
      "email":"String content", 
      "id":2147483647, 
      "name":"String content" 
     }, 
     "email":"String content", 
     "first_name":"String content", 
     "id":2147483647, 
     "last_name":"String content", 
     "reseller":{ 
      "email":"String content", 
      "id":2147483647, 
      "name":"String content", 
      "portal_css":"String content", 
      "portal_logo":"String content", 
      "portal_name":"String content", 
      "portal_url":"String content" 
     }, 
     "role":2147483647 
    } 
} 

的ID我已經嘗試了各種使用類似代碼的策略:

result = json.loads(json_result, object_hook=lambda d: namedtuple('X', d.keys())(*d.values())) 

def fun(d): 
    if 'id' in d: 
     yield d['id'] 
    for k in d: 
     if isinstance(d[k], list): 
      for i in d[k]: 
       for j in fun(i): 
        yield j 

我無法讓它正常工作。因此:

問題1: 我可以將json轉換爲(匿名)Python對象嗎?

問題2: 我可以編輯生成的字典嗎?

問題3: 當所有其他都失敗時;有沒有人有一個想法如何實現這一點?

非常感謝!

+3

'json.loads(json_result)'給你一個字典。 「匿名Python對象」是什麼意思?你能舉一個你想要的輸出的例子嗎? (我認爲你想散列ID,但我沒有看到任何散列任何代碼樣本的嘗試)。你想要什麼樣的哈希? –

+0

爲了澄清,你提到的「HTTP GET請求」是否需要傳遞整個字典或散列ID? – Aya

+0

@Aya,只需要散列編號,像/經銷商/ 28763298728 /經銷商/用戶代替/經銷商/ 1 /用戶 – Berdus

回答

2
json.loads(data) 

解析JSON字符串data,並返回一個Python dict,我想你可以打電話匿名,直到你把它分配給一個變量:

d = json.loads(data) 

然後,您可以修改字典到位。假設所有的響應具有相同的結構,你可以哈希id如下:

d["user"]["id"] = your_hash_function(d["user"]["id"]) 
+0

是這樣嗎?我試過了,但是沒有得到滿意的結果,我會再試一次。仍然在尋找更通用的方法,但是如果這樣做的話,我會很樂意在我的「WCFBackend」類功能中使用你的方法。 – Berdus

+0

@Berdus你的問題到底在哪裏?你是否遇到錯誤或者是否按預期工作? –

+0

我有點尷尬地說***結果[「用戶」] [「id」] =「測試」***似乎工作。在我的追求中,我必須忽略我的代碼中的錯誤那麼這個字典是不可變的,我仍然對一個更通用的方法感興趣,但是你的答案確實符合這個法案! – Berdus

1

這是我趕緊把在一起的解決方案。它通過字典遞歸併在密鑰爲id時替換值。這不是最終的解決方案,因爲它不支持列表,但我相信如果這對你有用,你可以從那裏拿走它?

def f(d): 
    _dict = {} 
    for k, v in d.items(): 
     if isinstance(v, dict): 
      _dict.update({k: f(v)}) 
     else: 
      if k == 'id': 
       print 'id found', v 
       v = EncryptValueHere(v) 
      _dict.update({k:v}) 

    return _dict 
+0

因爲OP是inter在改變價值觀念時,你不能直接改變原始字典中的值,而不是創建一個新的字典? – GodMan

+0

這將是可能的是的。畢竟,字典是通過引用傳遞的。將重新考慮這一點,以支持這一點。 除非這本字典非常龐大,否則不應該太過於取代整本字典的性能。 –

1

是的。 json.loads根據實際的json對象返回一個Python對象。查看conversion table瞭解更多詳情。沒有必要尋找一個特殊的匿名對象,就像你在.Net域中那樣。

result = json.loads(json_text) 

您可以編輯這個result到位:

result['user']['id'] = 'some_new_value' 

解析您的JSON當嘗試object_pairs_hook說法:

def hide_ids(o): 
    d = dict(o) 
    if 'id' in d: 
     d['id'] = '----{}----'.format(d['id']) 
    return d 

result = json.loads(json_text, object_pairs_hook=hide_ids) 

與您的首選模糊邏輯只是修改,你應該是好的去。

+0

看起來很有前途......感謝您的評論,我剛纔接受了ExP的回答。對於object_pairs_hook,爲+1。 PS:我當然看過文檔。在荷蘭,我們有一種說法(鬆散地翻譯):「睜眼看自己」。這可能是我的問題的根源。 – Berdus