2012-11-27 116 views
2

如何通過protoRPC返回類似對象dictprotoRPC:返回字典

我試着用FieldList無濟於事。我只看到以下字段定義:

 'IntegerField', 
     'FloatField', 
     'BooleanField', 
     'BytesField', 
     'StringField', 
     'MessageField', 
     'EnumField', 

回答

8

有兩種情況:

1)您的dict有一個明確定義的架構:這是最好的使用情況ProtoRPC的,如果可能,你應該嘗試將其納入模式。在這種情況下,您可以使用MessageField以及與您的字典中的架構匹配的Message類。

例如,而不是

{'amount': 31, 'type': 'fish', mine: False} 

你可以定義

from protorpc import messages 
class MyCatch(messages.Message): 
    amount = messages.IntegerField(1) 
    type = messages.StringField(2) 
    mine = messages.BooleanField(3) 

,然後通過

messages.MessageField(MyCatch, index, ...) 

2場使用此消息定義)您dict不有一個定義良好的模式:在這您可以使用json將字典轉儲爲字符串,並請求ensure_ascii=True以確保返回類型是字節(str)對象。那麼你可以使用BytesField

例如:

import json 

class MyMessage(messages.Message): 
    some_dict = messages.BytesField(1) 

my_dict = {'amount': 31, 'type': 'fish', mine: False} 
message = MyMessage(some_dict=json.dumps(my_dict, ensure_ascii=True)) 

採用ensure_ascii是可選的,因爲True是默認的,但是這可能會因環境而改變。

相反,您可以使用pickle序列化您的字典。方法pickle.dumps總是輸出ASCII /二進制,所以通過替換json.dumpspickle.dumps並刪除ensure_ascii=True,您會得到相同的結果。

+1

完美...謝謝! – jldupont

+1

在API中有變化嗎?當我這樣做時,我在客戶端獲得一個base64編碼的字符串。解碼字符串時,我得到了JSON。任何想法爲什麼? – vivekv

+0

你使用'messages.BytesField'嗎? – bossylobster

0

有點麻煩,但我更喜歡的東西很接近的字典實施protorpc配方:https://gist.github.com/linuxluser/32d4a9c36ca0b8715ad4

它被限制爲只使用字符串鍵和簡單的(不嵌套)值。但是如果你的數據適合那個類別,這個解決方案應該運行良好。

的想法有兩個部分:

  1. 創建一個新的字段類型MultiField,可容納的任意值類型。
  2. 創建類似於字典的類型MapField,該類型將鍵值對存儲在MultiField類型的列表中。

您可以使用它,像這樣:

import messages 
import mapfield 

class MyMessage(messages.Message): 
    some_dict = mapfield.MapField(1) 


my_message = MyMessage(some_dict={"foo": 7, "bar": False, "baz": 9.2, "qux": "nog"}) 

這只是一個開始。可能會更好。歡迎改進。 :)

1

它可以創建一個自定義JsonField這樣的:

In [1]: class JsonField(messages.StringField): 
      type = dict 

然後,您可以使用它作爲任何其他領域:

In [2]: class MyMessage(messages.Message): 
      data = JsonField(1) 

In [3]: m = MyMessage(data={"foo": "bar"}) 

In [4]: [getatttr(m, f.name) for f in m.all_fields()] 
Out [4]: [{'foo': 'bar'}]