Python 解析 Protobuf 文件

背景:

工作中遇到一個(gè)Python解析.proto文件的問題,這個(gè)問題涉及到protobuf文件之間的引用妙黍,即.proto文件A的message的其中一個(gè)字段,是.proto文件B中定義的message崩溪。

查閱了很多資料笼才,大多是介紹如何處理單個(gè)文件的尾膊,故自行回顧整理如下媳危。想直接看結(jié)果的小伙伴可以滑到末尾看重點(diǎn)。

目錄:

  1. 準(zhǔn)備.proto文件
  2. 環(huán)境配置
  3. 編譯.proto文件
  4. 變量讀取示例

準(zhǔn)備.proto文件

本文示例共涉及3個(gè).proto文件:

proto files.png

OrderTest.proto 文件:
這個(gè)文件引用了TimestampTest.proto文件冈敛。
OrderTest.proto 定義了一個(gè)Order message待笑,message中的兩個(gè)字段可以理解為商品名稱name和商品相關(guān)的時(shí)間timestamp,其中timestamp的類型是TimestampTest.proto 中定義的message抓谴。

syntax = "proto3";
import "TimestampTest.proto";
package Ding;

message Order {
    string name = 1;
    OrderTime timestamp = 100;
}

TimestampTest.proto 文件:
這個(gè)文件引用了 google/protobuf/timestamp.proto 文件暮蹂。
TimestampTest.proto 定義了一個(gè)OrderTime message,message中的兩個(gè)字段可以理解為下單時(shí)間和收貨時(shí)間齐邦。每個(gè)字段都是google/protobuf/timestamp.proto 中定義的message類型椎侠。

syntax = "proto3";
import "google/protobuf/timestamp.proto";
package Ding;

message OrderTime {
    google.protobuf.Timestamp placeTime = 1;
    google.protobuf.Timestamp receiveTime = 2;
}

google/protobuf/timestamp.proto 文件
這個(gè)文件可以從Git上找到第租,主要內(nèi)容如下:

message Timestamp {
  int64 seconds = 1;
  int32 nanos = 2;
}

筆者最終要用的是 OrderTest.proto 中的 Order message措拇。

環(huán)境配置

OS

筆者用的是 Windows 10

Python

筆者用的是 python 3.7.6,沒有安裝Python的小伙伴可以點(diǎn)擊這里下載慎宾。

Protobuf

其實(shí)就是安裝google.protobuf 這個(gè)依賴包丐吓,可以使用 pip install protobuf 進(jìn)行安裝。

安裝完成后可以在python安裝目錄中的這里找到:\Lib\site-packages\google趟据。
查看安裝的protobuf是什么版本:進(jìn)入\Lib\site-packages\google\protobuf目錄券犁,找到init.py文件。

init.png

通過導(dǎo)入包檢測(cè)是否安裝成功汹碱,沒有報(bào)錯(cuò)即表示安裝成功:
import protobuf.png

Protoc

protoc粘衬,即protocol compiler,是.proto文件的編譯器,它可以根據(jù)proto文件中的定義稚新,生成某編程語言可用的代碼勘伺。點(diǎn)擊這里下載對(duì)應(yīng)的protoc程序。
筆者是Windows系統(tǒng)褂删,64位飞醉,并且pip install 的 protobuf是3.11.3版本,所以筆者下載的是protoc-3.11.3-win64.zip

下載完成后解壓屯阀,把\protoc-3.11.3-win64\bin目錄添加進(jìn)path變量中缅帘。

查看protoc版本:
protoc.png

編譯.proto文件

打開cmd窗口,進(jìn)入.proto文件所在目錄难衰,輸入命令

protoc --python_out=. OrderTest.proto
protoc --python_out=. TimestampTest.proto

python_out:生成的文件適用于Python钦无,python_out=.表示生成的文件放在當(dāng)前文件夾,OrderTest.proto指明要操作哪個(gè).proto文件召衔。

沒有報(bào)錯(cuò)說明命令執(zhí)行成功铃诬,能看到在當(dāng)前目錄中多了一個(gè) OrderTest_pb2.py 文件和TimestampTest_pb2.py 文件。
protoc.png

注: 安裝 protobuf 的時(shí)候苍凛,已經(jīng)得到 google/protobuf/timestamp.proto 文件對(duì)應(yīng)的Python 代碼了趣席,不需要再手動(dòng)編譯。代碼也在這個(gè) \Lib\site-packages\google\protobuf 目錄下面醇蝴,文件名稱 timestamp_pb2.py宣肚。

變量讀取示例

新建一個(gè)Python 項(xiàng)目,新建一個(gè) example.py 文件悠栓,把 OrderTest_pb2.py 文件和 TimestampTest_pb2.py 文件復(fù)制粘貼到 example.py 文件所在目錄霉涨。
new project.png

在 example.py 文件中輸入代碼:

import OrderTest_pb2 as Order_Message

# create an Order instance
order = Order_Message.Order()

order.name = "ProductName"
order.timestamp.placeTime.seconds = 1583484823
order.timestamp.placeTime.nanos = 794162000

order.timestamp.receiveTime.seconds = 1583595823
order.timestamp.receiveTime.nanos = 794162000

print(order)

運(yùn)行這個(gè) example.py 文件,可以看到order變量已經(jīng)賦值成功了:
result.png

劃重點(diǎn)

如果遇到protobuf文件引用的情況惭适,訪問字段時(shí)必須一層一層訪問笙瑟,比如:

order.timestamp.receiveTime.seconds = 1583595823
order.timestamp.receiveTime.nanos = 794162000

這樣就會(huì)報(bào)錯(cuò):

import OrderTest_pb2 as Order_Message
import TimestampTest_pb2 as Order_Timestamp

timestamp = Order_Timestamp.OrderTime()
timestamp.placeTime.seconds = 1583484823
timestamp.receiveTime.seconds = 1583595823

# create an Order instance
order = Order_Message.Order()
order.timestamp = timestamp

報(bào)錯(cuò)如下:
error.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市癞志,隨后出現(xiàn)的幾起案子往枷,更是在濱河造成了極大的恐慌,老刑警劉巖凄杯,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件错洁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡戒突,警方通過查閱死者的電腦和手機(jī)屯碴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膊存,“玉大人导而,你說我怎么就攤上這事忱叭。” “怎么了今艺?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵窑多,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我洼滚,道長(zhǎng)埂息,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任遥巴,我火速辦了婚禮千康,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘铲掐。我一直安慰自己拾弃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布摆霉。 她就那樣靜靜地躺著豪椿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪携栋。 梳的紋絲不亂的頭發(fā)上搭盾,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音婉支,去河邊找鬼鸯隅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛向挖,可吹牛的內(nèi)容都是我干的蝌以。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼何之,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼跟畅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溶推,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤徊件,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后悼潭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庇忌,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舞箍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年舰褪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疏橄。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡占拍,死狀恐怖略就,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晃酒,我是刑警寧澤表牢,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贝次,受9級(jí)特大地震影響崔兴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛔翅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一敲茄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧山析,春花似錦堰燎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爵政,卻和暖如春仅讽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钾挟。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工何什, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人等龙。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓处渣,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蛛砰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罐栈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容