protoBuf-python學習筆記

2020-08-09 12:04:01

protoBuf官方簡介

protocol buffers 是一種語言無關、平臺無關、可延伸的序列化結構數據的方法
它可用於(數據)通訊協定、數據儲存等。

Protocol Buffers 是一種靈活,高效,自動化機制 機製的結構數據序列化方法
可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更爲簡單。

你可以定義數據的結構,然後使用特殊生成的原始碼
輕鬆的在各種數據流中使用各種語言進行編寫和讀取結構數據。
你甚至可以更新數據結構,而不破壞由舊數據結構編譯的已部署程式。

protobuf通過定義包含型別結構序列化資訊的檔案(.proto檔案),來編譯生成不同語言平臺的高效序列化程式程式碼

下載protoBuf編譯器

根據不同系統下載不同protoc編譯器,在windows下下載windows後綴的
protoc-3.12.0-rc-1-winxxx.zip

解壓後得到的目錄中,bin目錄中的protoc.exe就是編譯protoc程式碼命令

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2020/5/5      1:24                bin
d-----         2020/5/5      1:24                include
-a----         2020/5/5      1:24            724 readme.txt

把protoc.exe設定到Path環境變數

編譯proto到python程式碼

protoc --python_out=$DST_DIR $SRC_DIR/your.proto

其中,DST_DIR指定編譯的go程式碼輸出路徑,SRC_DIR/your.proto指定proto檔案,最後一個參數是要編譯的proto檔名
最終生成了程式碼檔案xxx_pb2.py

syntax宣告

一般在proto檔案開頭使用syntax宣告proto版本,預設是proto2
比如

syntax = "proto3";

匯入包

通過import語句匯入proto包,比如

import "google/protobuf/struct.proto"

定義message

protobuf中使用關鍵字message定義結構,並且結構中可以巢狀定義結構,比如

message A {}
message B {
	message C {
	}
}

內嵌型別最終會編譯爲以外部型別名稱_名稱作爲型別名稱的結構體,比如此處,生成的結構體有3個,分別是

type A struct {...}
type B struct {...}
type B_C struct {...}

定義欄位

基本定義語法如下,其中type是型別,name是欄位名稱,num是數據編號
當反序列化時,會把對應數據編號對應的數據填充到對應欄位
對於type,如果是message型別,在編譯爲語言程式碼時會被轉化爲對應的指針型別

type  name = num
  • 基本型別
    message A {
    	string name = 1;
    }
    
  • message型別
    message B {
    	string name = 1;
    }
    message A {
    	B b = 1;
    }
    
  • map
    message A {
    	map<string,int> pic = 1;
    }
    
  • 列舉
    列舉型別會被編譯爲整型的替代型別,列舉值會變爲const變數,以型別名_列舉量名作爲名稱
    與message類似,列舉也可以巢狀在型別中,最終會編譯爲以外部型別名稱_列舉名稱作爲型別名稱
    比較獨特的,列舉列舉中列舉量的數值就是他們編譯後程式碼中常數的初始化數值,第一個列舉量的數據編號必須是0
    message A{
      enum Color{
        RED = 0;
        BLACK = 1;
      }
      Color c = 1;
    }
    enum Day{
        ONE = 0;
        TWO = 1;
    }
    
  • repeated型別(陣列)
    通過在型別前加上關鍵字repeated代表其爲陣列型別,該欄位序列化可能出現0次或多次,比如
    message B{}
    message A{
      repeated B bs= 1;
    }
    
    最終生成
    type B struct {...}
    type A struct {
    	...
    	Bs []*B ...
    }
    

定義服務

proto支援通過service與rpc關鍵字分別定義rpc服務和rpc方法,proto預設不會生成rpc程式碼,需要結合對應的rpc外掛(grpc、twirp等)編譯纔會生成
比如如下程式碼,定義了一個service,提供一個search的rpc呼叫方法,接收一個Request型別的參數,返回Response型別的結果

message Request{}
message Response{}
service Search{
	rpc search(Request) returns(Response);
}

結合grpc生成py的rpc程式碼

需要先安裝python相關的grpc模組(下面 下麪使用國內映象)

pip install grpcio-tools -i https://pypi.tuna.tsinghua.edu.cn/simple

然後使用grpc模組結合protobuf生成對應的rpc的server和client

python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. test.proto

這時發現本次proto編譯比上次多了一個test_py2_grpc.py,包含rpc的內容
更多文章,請搜尋公衆號歪歪梯Club
更多资料,请搜索公众号编程宝可梦