python中的protobuf到json (Protobuf to json in python)


問題描述

python中的protobuf到json (Protobuf to json in python)

我有一個對象,我在 Python 中使用 protobuf 進行反序列化。當我打印該對象時,它看起來像一個 python 對象,但是當我嘗試將其轉換為 json 時,我遇到了各種各樣的問題。

例如,如果我使用 json.dumps() 我知道對象(從 protoc 生成的代碼)不包含 _ dict _ 錯誤。

如果我使用 jsonpickle 我獲取 UnicodeDecodeError: 'utf8' codec can't decode byte 0x9d in position 97: invalid start byte

下面的測試代碼正在使用 jsonpickle 並出現上面顯示的錯誤。

if len(sys.argv) < 2:
    print ("Error: missing ser file")
    sys.exit()
else :
    fileLocation = sys.argv[1]

org = BuildOrgObject(fileLocation) 

org = org.Deserialize()


#print (org)
jsonObj = jsonpickle.encode(org)
print (jsonObj)

## 參考解法 #### 方法 1:

I'd recommend using protobuf↔json converters from google's protobuf library:

from google.protobuf.json_format import MessageToJson

json_obj = MessageToJson(org)

You can also serialise the protobuf to a dictionary:

from google.protobuf.json_format import MessageToDict
dict_obj = MessageToDict(org)

Refer to the protobuf package API documentation: https://developers.google.com/protocol‑buffers/docs/reference/python/ (see module google.protobuf.json_format).

方法 2:

If you need to go straight to json take a look at the protobuf‑to‑json library, but you'll have to install that manually.

But I would recommend that you use the protobuf‑to‑dict library instead for a few reasons:

  1. It is accessible from pypi so you can simply pip install protobuf‑to‑dict or include it in a requirements.txt
  2. dict can be converted to json and might be more useful than a json string

方法 3:

You can also user SerializeToString.

org.SerializeToString()

方法 4:

If you are using an older version that doesn't has the preserving_proto_field_name field:

from google.protobuf.json_format import MessageToJson
def proto_to_json(proto_obj):
    json_obj = MessageToJson(proto_obj):
    json_obj = MessageToJso, including_default_value_fields=True)
    # Change lowerCamelCase of google Json conversion to the snake_case as in original protobuf
    dict_obj = dict((re.sub(r'(?<!^)(?=[A‑Z])', '_', k).lower(),v) for k, v in json.loads(json_obj).items())
    if hasattr(proto_obj, 'uuid'):
        dict_obj["uuid"] = proto_obj.uuid.encode("hex")
    return json.dumps(dict_obj, indent=4, sort_keys=True)

方法 5:

Here's my function to convert a proto3 object to a JSON object (i.e. Python dictionary):

def protobuf_to_dict(proto_obj):
    key_list = proto_obj.DESCRIPTOR.fields_by_name.keys()
    d = {}
    for key in key_list:
        d[key] = getattr(proto_obj, key)
    return d

Since the converters from Google's protobuf library don't seem to work in some cases with the 3.19 version, this function leverages the Descriptor class present on each Protobuf object.

Here, getattr(obj, string_attribute) returns the value given by obj.attribute

(by exHashdenis‑suminKevin HillShubham Kanyalvr286Nirav)

參考文件

  1. Protobuf to json in python (CC BY‑SA 3.0/4.0)

#protocol-buffers #Python #JSON






相關問題

通過 Method.invoke() 調用靜態方法給了我 NPE (Static method invocation via Method.invoke() gave me NPE)

python中的protobuf到json (Protobuf to json in python)

如何序列化/反序列化使用 ScalaPB 的“oneof”的 protobuf 消息? (How to serialize/deserialize a protobuf message that uses 'oneof' with ScalaPB?)

序列化和反序列化未知的繼承類型 (Serializing and deserializing unknown inherited types)

Thrift 與協議緩衝區 (Thrift vs Protocol buffers)

如何在客戶端排除導入 (How to exclude an import on client side)

為什麼當我安裝了 Tensorflow 的所有庫後,會出現無目錄錯誤? (Why do I get a no directory error, when I have installed all the libraries for Tensorflow?)

如何為 C# <proto/> 定義傳遞experimental_allow_proto3_optional 以在proto3 中啟用可選? (How to pass experimental_allow_proto3_optional for C# <proto/> definitions to enable optional in proto3?)

CentOS7 的 libprotobuf-lite.so 文件在 CentOS8 機器上工作嗎? (is libprotobuf-lite.so file from CentOS7 working in CentOS8 machine?)

protogen - 支持 <Property> 指定的語法 (protogen - support the <Property>Specified syntax)

.Net 字典類型在 protobuff (.Net dictionary type in protobuff)

為什麼 protobuf 更喜歡代碼生成器而不是運行時動態加載 (why protobuf prefer code-generator other than dynamic loading at runtime)







留言討論