zoukankan      html  css  js  c++  java
  • 【转】Python使用ProtoBuffer

     转自:https://www.cnblogs.com/fanghao/p/9811187.html

    Protocol Buffers,是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。
    就可读性而言感觉没有JSON直接,不过由于使用二进制传输,效率得到大大提升,用在RPC比较合适

    1. 安装

    在Ubuntu下非常方便

    pip install protobuf    # 安装protobuf库
    sudo apt-get install protobuf-compiler  # 安装protobuf编译器
    

    2. 定义数据类型

    syntax = "proto2";
    
    package demo; // 申明包,防止命名冲突
    
    // message类似于class,用于定义一个数据结构
    // message之间可以相互嵌套
    message Person{
        required string name = 1; // 1,2,3是字段的标识符
        required int32 id = 2;
        optional string email = 3;
    
        enum PhoneType {
            MOBILE = 1;
            HOME = 2;
            WORK = 3;
        }
    
        message PhoneNumber {
            required string number = 1;
            optional PhoneType type = 2 [default = HOME];
        }
    
        // 修饰符:required表示必须有,optional表示可选
        // repeated表示可有多个(包括0个)
        repeated PhoneNumber phones = 4;
    }
    
    message AdressBook {
        required Person people = 1;
    }
    

    3.编译

    # 通用格式
    protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto
    
    # 这里,我们直接在当前目录编译
    protoc --python_out=./ ./addressbook.proto
    

    结果会在目标地址下生成addressbook_pb2.py

    4. 文件写入

    # coding=utf-8
    import addressbook_pb2
    
    address_book = addressbook_pb2.AdressBook()
    
    #### person1 ###
    p1 = address_book.people.add()
    p1.name = "Jack"
    p1.id = 20
    p1.email = "jack@qq.com"
    
    phone_num1 = p1.phones.add()
    phone_num1.number = "123"
    phone_num1.type = 2  # 与默认类型不同
    
    phone_num2 = p1.phones.add()
    phone_num2.number = "456"
    print(p1)
    
    ### person2 ###
    p2 = address_book.people.add()
    p2.name = "Chen"
    p2.id = 21
    
    # 遍历,输出repeated类型的成员
    for phone in p1.phones:
        print(phone.type)
    
    # 保存到二进制文件
    f = open("address.pb", "wb")
    f.write(address_book.SerializeToString()) # 调用串行化接口
    f.close()
    

    运行输出

    name: "Jack"
    id: 20
    email: "jack@qq.com"
    phones {
      number: "123"
      type: HOME
    }
    phones {
      number: "456"
    }
    
    2
    3
    

    5. 文件读取

    # coding=utf-8
    import addressbook_pb2
    
    f = open("address.pb", "rb")
    address_book = addressbook_pb2.AdressBook()
    address_book.ParseFromString(f.read())
    f.close()
    
    for person in address_book.people:
        print(person.name)
    

    运行输出

    Jack
    Chen
    

    6.小结

    protobuffer用二进制来传输,性能应该会有提升.但是双方都要保留一份编译后的pb2文件,相当于协议,感觉稍重稍复杂

  • 相关阅读:
    C++概念性总结
    友元函数
    C++指针概念
    Linux下多线程(clone()线程)
    Qt5模块化详细总结
    C++有符号与无符号之间的转换问题
    使用C++test工具做Qt代码静态分析
    QT函数带有外部链接但没有在头文件中声明(QT noreturn属性添加)
    Linux之Docker手动创建Docker容器
    我在思考一个很变态的社会趋向
  • 原文地址:https://www.cnblogs.com/zcsh/p/14983073.html
Copyright © 2011-2022 走看看