美文网首页软件测试
Python 解析 Protobuf 文件

Python 解析 Protobuf 文件

作者: 左左007 | 来源:发表于2020-03-08 16:50 被阅读0次

    背景:

    工作中遇到一个Python解析.proto文件的问题,这个问题涉及到protobuf文件之间的引用,即.proto文件A的message的其中一个字段,是.proto文件B中定义的message。

    查阅了很多资料,大多是介绍如何处理单个文件的,故自行回顾整理如下。想直接看结果的小伙伴可以滑到末尾看重点。

    目录:

    1. 准备.proto文件
    2. 环境配置
    3. 编译.proto文件
    4. 变量读取示例

    准备.proto文件

    本文示例共涉及3个.proto文件:

    proto files.png
    OrderTest.proto 文件:
    这个文件引用了TimestampTest.proto文件。
    OrderTest.proto 定义了一个Order message,message中的两个字段可以理解为商品名称name和商品相关的时间timestamp,其中timestamp的类型是TimestampTest.proto 中定义的message。
    syntax = "proto3";
    import "TimestampTest.proto";
    package Ding;
    
    message Order {
        string name = 1;
        OrderTime timestamp = 100;
    }
    

    TimestampTest.proto 文件:
    这个文件引用了 google/protobuf/timestamp.proto 文件。
    TimestampTest.proto 定义了一个OrderTime message,message中的两个字段可以理解为下单时间和收货时间。每个字段都是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 文件
    这个文件可以从Git上找到,主要内容如下:

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

    笔者最终要用的是 OrderTest.proto 中的 Order message。

    环境配置

    OS

    笔者用的是 Windows 10

    Python

    笔者用的是 python 3.7.6,没有安装Python的小伙伴可以点击这里下载。

    Protobuf

    其实就是安装google.protobuf 这个依赖包,可以使用 pip install protobuf 进行安装。

    安装完成后可以在python安装目录中的这里找到:\Lib\site-packages\google。
    查看安装的protobuf是什么版本:进入\Lib\site-packages\google\protobuf目录,找到init.py文件。

    init.png 通过导入包检测是否安装成功,没有报错即表示安装成功: import protobuf.png

    Protoc

    protoc,即protocol compiler,是.proto文件的编译器,它可以根据proto文件中的定义,生成某编程语言可用的代码。点击这里下载对应的protoc程序。
    笔者是Windows系统,64位,并且pip install 的 protobuf是3.11.3版本,所以笔者下载的是protoc-3.11.3-win64.zip

    下载完成后解压,把\protoc-3.11.3-win64\bin目录添加进path变量中。

    查看protoc版本: protoc.png

    编译.proto文件

    打开cmd窗口,进入.proto文件所在目录,输入命令

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

    python_out:生成的文件适用于Python,python_out=.表示生成的文件放在当前文件夹,OrderTest.proto指明要操作哪个.proto文件。

    没有报错说明命令执行成功,能看到在当前目录中多了一个 OrderTest_pb2.py 文件和TimestampTest_pb2.py 文件。 protoc.png

    注: 安装 protobuf 的时候,已经得到 google/protobuf/timestamp.proto 文件对应的Python 代码了,不需要再手动编译。代码也在这个 \Lib\site-packages\google\protobuf 目录下面,文件名称 timestamp_pb2.py。

    变量读取示例

    新建一个Python 项目,新建一个 example.py 文件,把 OrderTest_pb2.py 文件和 TimestampTest_pb2.py 文件复制粘贴到 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)
    
    运行这个 example.py 文件,可以看到order变量已经赋值成功了: result.png

    划重点

    如果遇到protobuf文件引用的情况,访问字段时必须一层一层访问,比如:

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

    这样就会报错:

    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
    
    报错如下: error.png

    相关文章

      网友评论

        本文标题:Python 解析 Protobuf 文件

        本文链接:https://www.haomeiwen.com/subject/aqlddhtx.html