python中protobuf和json互相轉換應用處理方法
在實際信息系統(tǒng)開發(fā)中,經常會用到各種各樣的協議,網絡協議常用的有http,tcp,udp等,傳輸數據格式協議有json,xml,TLV等。本節(jié)將給大家介紹一種節(jié)省帶寬數據協議,谷歌的ProtoBuf協議,該協議由于是開源免費的,有多種語言的調用接口,比如常見C,C++,java,Python,C#,PHP ... 所以國內很多公司都在使用。
本人所在項目引擎使用C++語言開發(fā),外部輸入的protobuf字節(jié)流在內部都是使用C++來處理,上次客戶端想要用他們的數據來演示效果,讓我去客戶現處理客戶數據,然后導入我們引擎進行效果展示??蛻衄F場數據是excel文件,出差時沒有相關的處理工具,本人只好現場開發(fā),提取客戶excel中的數據,轉換成json,再轉換成我們引擎能夠識別的ProtoBuf字節(jié)流。所以在此記錄一下python中protobuf和json的相互轉換的處理方法。
protobuf目前有proto2和proto3兩個版本,本文所介紹的是基于proto3,在Python 3.6.9環(huán)境下運行。
1.ProtoBuf中定義字段與各語言類型對應表
2.ProtoBuf使用方法
2.1 下載安裝protobuf生成器
protobuf生成器可以通過源碼編譯得到,也可以下載別人編譯好的應用程序
GitHub上下載地址如下
GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format
2.2 定義protobuf格式的應用協議
下面以公司為業(yè)務構造協議,舉例如下:
message.proto
syntax = "proto3"; message Empty {} message Address { string province = 1; string city = 2; string county = 3; string detail = 4; } message Person { int32 id = 1; string name = 2; Sex sex = 3; Address addr = 4; string email = 5; string phone = 6; enum Sex { MAIL = 0; FEMAIL = 1; } } message Company { string name = 1; repeated Person employee = 2; }
2.3 生成協議調用api
在Python中,生成方式如下:
/home/test/protobuf/bin/protoc -I=/home/test/Python --python_out=/home/test/Python message.proto
或者
/home/test/protobuf/bin/protoc --proto_path=/home/test/Python --python_out=/home/test/Python message.proto
附C++生成方式如下:
/home/test/protobuf/bin/protoc -I=/home/test/cpp --cpp_out=/home/test/cpp message.proto
或者
/home/test/protobuf/bin/protoc --proto_path=/home/test/cpp --cpp_out=/home/test/cpp message.proto
說明:
-I 或者 --proto_path用來指定proto接口定義文件所在路徑
--python_out表示生成Python調用的接口
--cpp_out表示生成C++調用的接口
2.4 調用
引入protobuf庫和2.3生成的接口,就可以進行自己的業(yè)務開發(fā)了
3. Json轉Protobuf
調用舉例如下:
#coding=utf-8 import message_pb2 from google.protobuf import json_format import json #json轉PB def jsonToPB(): json_addr = {} json_addr["province"] = "shanxisheng" json_addr["city"] = "shangluoshi" json_addr["county"] = "luonanxian" json_addr["detail"] = "guchengzhenliyuancunsanzu" json_person = {} json_person["id"] = 9999 json_person["name"] = "liudehua" json_person["sex"] = 1 json_person["addr"] = json_addr json_person["email"] = "123456789@163.com" json_person["phone"] = "859348598948656" strjson = json.dumps(json_person, indent=4) print(strjson) json_to_pb = json_format.Parse(strjson, message_pb2.Person()) print(json_to_pb.SerializeToString()) if __name__ == "__main__": print("=============Json to PB==========") jsonToPB() #coding=utf-8 import message_pb2 from google.protobuf import json_format import json #json轉PB def jsonToPB(): json_addr = {} json_addr["province"] = "shanxisheng" json_addr["city"] = "shangluoshi" json_addr["county"] = "luonanxian" json_addr["detail"] = "guchengzhenliyuancunsanzu" json_person = {} json_person["id"] = 9999 json_person["name"] = "liudehua" json_person["sex"] = 1 json_person["addr"] = json_addr json_person["email"] = "123456789@163.com" json_person["phone"] = "859348598948656" strjson = json.dumps(json_person, indent=4) print(strjson) json_to_pb = json_format.Parse(strjson, message_pb2.Person()) print(json_to_pb.SerializeToString()) if __name__ == "__main__": print("=============Json to PB==========") jsonToPB()
說明:如上先使用json.dumps將字典打包成json字符串,然后使用json_format.Parse將json字符串轉換為ProtoBuf對象,然后將ProtoBuf對象序列化為字節(jié)流打印輸出。
運行結果如下:
4. Protobuf轉Json
調用代碼如下:
#coding=utf-8 import message_pb2 from google.protobuf import json_format import json #PB轉json字符串 def pbToJson(pb): strjson = json_format.MessageToJson(pb) print(strjson) def buildPB(): person = message_pb2.Person() person.id = 110 person.name = "Boss" person.addr.province = "anm" person.addr.city = "qiuchongtian" person.addr.county = "ABC" person.addr.detail = "123" person.sex = message_pb2.Person.Sex.MAIL person.email = "rulaifo@qq.com" person.phone = "75211234567890" #PB對象序列化為字節(jié)流 pb1 = person.SerializeToString() person1 = message_pb2.Person() #字節(jié)流流構造PB對象 person1.ParseFromString(pb1) com = message_pb2.Company() com.name = 'USA' idlist = [111, 222, 222] for id in idlist: per = com.employee.add() per.id = id print(com) print(person1) return person1 if __name__ == "__main__": #構造PB pb = buildPB() print("=============PB to Json==========") pbToJson(pb)
說明:程序中使用message_pb2.Person()初始化得到一個protobuf對象person,然后給對象person各個屬性賦值,然后將person序列化為pb1,使用message_pb2.Person()構造另一個對象
person1,person1使用person序列化后的pb1初始化,此時person1和person具有相同的屬性。
使用message_pb2.Company()構造一個公司對象com,然后給屬性賦值。最后使用json_format.MessageToJson將protobuf類型的person對象轉化為json字符串打印輸出。
運行結果如下:
到此這篇關于python中protobuf和json互相轉換應用的文章就介紹到這了,更多相關python protobuf和json互相轉換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
簡單理解Python中的事件循環(huán)EventLoop
在 python 3中,加入了 asyncio 模塊,來實現協程,其中一個很重要的概念是事件循環(huán),本文我們就來自己實現一個相對簡單的EventLoop,從而了解一下事件循環(huán)是如何進行運轉的吧2023-10-10conda創(chuàng)建環(huán)境過程出現"Solving?environment:?failed"報錯的詳細解
很長一段時間沒用conda了,然后突然使用conda創(chuàng)建環(huán)境報錯,所以下面這篇文章主要給大家介紹了關于conda創(chuàng)建環(huán)境過程出現"Solving?environment:?failed"報錯的詳細解決方法,需要的朋友可以參考下2022-11-11Python實現字典按key或者value進行排序操作示例【sorted】
這篇文章主要介紹了Python實現字典按key或者value進行排序操作,結合實例形式分析了Python針對字典按照key或者value進行排序的相關操作技巧,需要的朋友可以參考下2019-05-05Python+Pygame實戰(zhàn)之實現小蜜蜂歷險記游戲
這篇文章主要為大家介紹了如何利用Python中的Pygame模塊實現小蜜蜂歷險記游戲,文中的示例代碼講解詳細,對我們學習Python游戲開發(fā)有一定幫助,需要的可以參考一下2022-08-08