python中使用 protocol buffer(Protobuf)

项目中引入proto的依赖

【两种方法】:
方法1、 官网下载对应的语言包,https://github.com/protocolbuffers/protobuf/releases 

这里选择python下载 https://github.com/protocolbuffers/protobuf/releases/download/v3.5.1/protobuf-python-3.5.1.tar.gz

解压后进入python-protobuf-3.5.1/python目录,执行python3 setup.py install


方法2 、【推荐】命令行执行pip3 install protobuf,此时会下载最新的protobuf版本,如果下载的版本与本地安装的proto命令版本不一致,有可能导致异常,所以此时最好指定要下载的版本号:pip3 install protobuf==3.5.1

【注意】

  • 上面的安装方式是全局安装,安装成功后对应的依赖包都会被安装到对应的site-packages目录下,比如/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages使用IDE开发时,如PyCharm,绑定interpreter时要注意勾选inherit global site-packages,这样项目才能使用全局依赖中的所有包
  • 如果只是为当前项目安装依赖包可以不勾选inherit global site-packages,然后进入当前项目依赖的pip目录,即Location指定的路径下,执行./bin/pip install protobuf==3.5.1来安装需要的依赖包

准备proto文件

  • proto示例文件参考[Protocol Buffer学习笔记(Java&NodeJS)]
    (https://www.jianshu.com/p/55f4b4b22dd2)
  • python同时支持proto2和proto3,所以如果基于proto3,这里注意去掉其中的requiredoptional,因为这里要求语法严格遵循proto3,不能在属性前出现requiredoptional,同时文件顶端要明确syntax = "proto3";

生成proto对应的python文件

  • 命令行执行
    protoc --python_out=. OTIpcDef.proto
  • 此时会在当前目录下生成OTIpcDef_pb2.py,将该文件拷贝到项目中,比如放到项目根目录的proto目录下

python中使用protobuf

from proto import OTIpcDef_pb2

otIpcList = OTIpcDef_pb2.OTIpcList()

# list类型数据创建方式
otIpc = otIpcList.otpic.add()
otIpc.CompanyId = "companyId"
otIpc.Source = "Source"
otIpc.IPCType = OTIpcDef_pb2.baseInfoCompany
# list类型数据创建方式
baseInfoCompany = otIpc.baseInfoCompany.add()


# print(type(baseInfoCompany))

baseInfoCompany.Address = 110011
baseInfoCompany.CompanyId = "companyId"
baseInfoCompany.CompanyName = "companyName中文"
baseInfoCompany.Identifier = "identifier"
baseInfoCompany.BusinessScope = "BusinessScope"
baseInfoCompany.ContactAddress = "ContactAddress"
baseInfoCompany.EconomicType = "EconomicType"
baseInfoCompany.RegCapital = "RegCapital"
baseInfoCompany.LegalName = "LegalName"
baseInfoCompany.LegalID = "LegalID"
baseInfoCompany.LegalPhone = "LegalPhone"
baseInfoCompany.State = 0
baseInfoCompany.Flag = 1
baseInfoCompany.UpdateTime = 20180226121212

otIpc2 = otIpcList.otpic.add()
otIpc2.CompanyId = "companyId"
otIpc2.Source = "Source"
otIpc2.IPCType = OTIpcDef_pb2.baseInfoCompanyStat
baseInfoCompanyStat = otIpc2.baseInfoCompanyStat.add()
baseInfoCompanyStat.CompanyId = "companyId"
baseInfoCompanyStat.DriverNum = 10
baseInfoCompanyStat.Flag = 0
baseInfoCompanyStat.UpdateTime = 20180226121212
baseInfoCompanyStat.VehicleNum = 5

print("============================================")

# print(otIpc)
print(otIpcList)
print("============================================")
# 序列化
b = otIpcList.SerializeToString()
# 打印二进制数据
print(b)

print("============================================")

otIpcList2 = OTIpcDef_pb2.OTIpcList()
# 反序列化
otIpcList2.ParseFromString(b)

print(otIpcList2)

 

python中使用protobuf 实例2

data.proto:

syntax = "proto3";

package protobuf;

message SendData {
    int32 request_type = 1;
    int32  tool_type = 2;
    string data = 3;
}


message RevcData {
    int32 status = 1;
    string error_msg = 2;
    int32 request_type = 3;
    int32  tool_type = 4;
    string data = 5;
}

执行命令: 

protoc --python_out=. data.proto

得到 data_pb2.py:

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: data.proto

import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()




DESCRIPTOR = _descriptor.FileDescriptor(
  name='data.proto',
  package='protobuf',
  syntax='proto3',
  serialized_options=None,
  serialized_pb=_b('\n\ndata.proto\x12\x08protobuf\"A\n\x08SendData\x12\x14\n\x0crequest_type\x18\x01 \x01(\x05\x12\x11\n\ttool_type\x18\x02 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\t\"d\n\x08RevcData\x12\x0e\n\x06status\x18\x01 \x01(\x05\x12\x11\n\terror_msg\x18\x02 \x01(\t\x12\x14\n\x0crequest_type\x18\x03 \x01(\x05\x12\x11\n\ttool_type\x18\x04 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\tb\x06proto3')
)




_SENDDATA = _descriptor.Descriptor(
  name='SendData',
  full_name='protobuf.SendData',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
    _descriptor.FieldDescriptor(
      name='request_type', full_name='protobuf.SendData.request_type', index=0,
      number=1, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='tool_type', full_name='protobuf.SendData.tool_type', index=1,
      number=2, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='data', full_name='protobuf.SendData.data', index=2,
      number=3, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=_b("").decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=24,
  serialized_end=89,
)


_REVCDATA = _descriptor.Descriptor(
  name='RevcData',
  full_name='protobuf.RevcData',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
    _descriptor.FieldDescriptor(
      name='status', full_name='protobuf.RevcData.status', index=0,
      number=1, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='error_msg', full_name='protobuf.RevcData.error_msg', index=1,
      number=2, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=_b("").decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='request_type', full_name='protobuf.RevcData.request_type', index=2,
      number=3, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='tool_type', full_name='protobuf.RevcData.tool_type', index=3,
      number=4, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
    _descriptor.FieldDescriptor(
      name='data', full_name='protobuf.RevcData.data', index=4,
      number=5, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=_b("").decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=91,
  serialized_end=191,
)

DESCRIPTOR.message_types_by_name['SendData'] = _SENDDATA
DESCRIPTOR.message_types_by_name['RevcData'] = _REVCDATA
_sym_db.RegisterFileDescriptor(DESCRIPTOR)

SendData = _reflection.GeneratedProtocolMessageType('SendData', (_message.Message,), {
  'DESCRIPTOR' : _SENDDATA,
  '__module__' : 'data_pb2'
  # @@protoc_insertion_point(class_scope:protobuf.SendData)
  })
_sym_db.RegisterMessage(SendData)

RevcData = _reflection.GeneratedProtocolMessageType('RevcData', (_message.Message,), {
  'DESCRIPTOR' : _REVCDATA,
  '__module__' : 'data_pb2'
  # @@protoc_insertion_point(class_scope:protobuf.RevcData)
  })
_sym_db.RegisterMessage(RevcData)


# @@protoc_insertion_point(module_scope)

测试文件 send.py:

# -*- coding: utf-8 -*-

import data_pb2
import json


if __name__ == "__main__":

    test_dict =  {
        "test1":1,
        "test2":2
    }
    sendData = data_pb2.SendData()
     
    sendData.request_type = 1
    sendData.tool_type = 1
    sendData.data = json.dumps(test_dict)

     
    print("============================================")
     
    # print(otIpc)
    print(sendData)
    print("============================================")
    # 序列化
    b = sendData.SerializeToString()
    # 打印二进制数据
    print(b)
     
    print("============================================")
     
    sendData2 = data_pb2.SendData()
    # 反序列化
    sendData2.ParseFromString(b)
    print(sendData2)

执行结果如下:

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值