ProtoBuf与Python结合使用初步

Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++JAVAPython等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。

Protocol Buffers经常被简称为protobuf。

GitHub地址:https://github.com/google/protobuf

谷歌官方文档:https://developers.google.com/protocol-buffers/

安装方法:现在GitHub上下载Release的Python版本,我使用Ubuntu系统,解压后执行安装命令:

$ ./configure
$ make
$ sudo make install

安装后测试protoc命令,该程序用于把proto文件翻译成目标代码:

$ protoc --version
$ libprotoc 3.0.0

安装完后需要安装python支持,我采用pip安装:

$ sudo pip install --upgrade protobuf

 这样就可以了。

然后编写一个最简单的proto文件:test_proto.proto

syntax = "proto2";
message Person {

}

相当于定义了一个结构Person,但是没有任何成员,使用编译命令把它转成python代码:

$ protoc --python_out=./ ./test_proto.proto

自动生成了一个test_proto_pb2.py

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: test_proto.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
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()




DESCRIPTOR = _descriptor.FileDescriptor(
  name='test_proto.proto',
  package='',
  syntax='proto2',
  serialized_pb=_b('\n\x10test_proto.proto\"\x08\n\x06Person')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)




_PERSON = _descriptor.Descriptor(
  name='Person',
  full_name='Person',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  options=None,
  is_extendable=False,
  syntax='proto2',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=20,
  serialized_end=28,
)

DESCRIPTOR.message_types_by_name['Person'] = _PERSON

Person = _reflection.GeneratedProtocolMessageType('Person', (_message.Message,), dict(
  DESCRIPTOR = _PERSON,
  __module__ = 'test_proto_pb2'
  # @@protoc_insertion_point(class_scope:Person)
  ))
_sym_db.RegisterMessage(Person)


# @@protoc_insertion_point(module_scope)

 

然而我们使用的时候不用关心这个文件,修改.proto文件,重新编译即可。

在test_proto.proto中加个变量试试:

syntax = "proto2";
message Person {
    required string name = 1;
}

编译以后,生成的代码和上一版本做个比较:


主要就是在fields里增加了内容。

有了fields,我们就可以用来存数据了,主要使用SerializeToString()和ParseFromString()来序列化和反序列化数据结构,最简单的示例:

from test_proto_pb2 import Person

FILE_PATH = './my_person.raw'


def write_test():
    person = Person()
    person.name = 'my name is hello world!!!'
    f = open(FILE_PATH, "wb")
    f.write(person.SerializeToString())
    f.close()


def read_test():
    person = Person()
    f = open(FILE_PATH, "rb")
    person.ParseFromString(f.read())
    f.close()
    print person.name


if __name__ == "__main__":
    write_test()
    read_test()

 

Protocol Buffer协议可以用来将数据存文件,当然主要用于网络传输数据,采用二进制的形式传输不易被破解,还节省流量,因为几乎没有可读性。

猜你喜欢

转载自hzy3774.iteye.com/blog/2323428