Protobuf在Python中的使用

参看:

http://www.open-open.com/home/space.php?uid=37924&do=blog&id=5873    (protobuf协议语言指南)

http://blog.csdn.net/program_think/article/details/4229773      (Protocol Buffers介绍 (GOOD)

http://blog.sina.com.cn/s/blog_7575a6190101u86f.html    (GOOD)

Protobuf在Python中的使用

本文原创自 esbat的博客,转载请注明出处

protocol buffer的安装

$ wget http://protobuf.googlecode.com/files/protobuf-2.4.0a.tar.gz
$ tar zxvf protobuf-2.4.0a.tar.gz
$ cd protobuf-2.4.0a
$ ./configure
$ make
$ make check
$ make install
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
protocol buffer对python的支持

$ cd python/
$ python setup.py test
$ python setup.py install
protocol buffer对应*.proto文件生成python代码

protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/ruledb_pb2.proto
  • $SRC_DIR表示*.proto所在文件夹路径
  • $DST_DIR表示要把python代码生成在哪个文件夹
  • 本例的*.proto文件采用ruledb_pb2.proto
调用protobuf的常规方法
import ruledb_pb2
ruledb = ruledb_pb2.UrlRule()
ruledb.ParseFromString(Rule)
print ruledb
在调用特殊自定义protobuf的方法

  • 使用默认的接口writeTo(OutputStream)/mergeFrom(InputStream) 使用这种方法有一个很大的缺点,当用mergeFrom从InputStream中读数据时,默认会一次把文件中的所有message都读完,直到文件结束或读取格式出错,不管你写了多少条记录。 如写了10条message,那最后只能读出一条message。这种方式只能适用于存取一条记录
  • 在protobuf内部,真正用来序列化/反序列化message的流是CodedInputStream及 CodedOutputStream 相当于通过CodedInputStream及CodedOutputStream,protobuf自定义了写数据的协议,使得protobuf可以跨语言访问(不同语言间,都实现了相同的读写流协议)
  • 当开发人员直接java或者c++调用CodedInputStream及CodedOutputStream方法时,因为protobuf生成的python代码里没有对应的该方法,所以需要自己写解释代码
  • 例如在ruledb中的存储,是用前两个字节表示数据长度,把一个个message直接堆在一起,读取时需要转换成protobuf能读的形式,调用如下代码
from google.protobuf.internal import decoder
import ruledb_pb2
    def pb_convert(self,file):
        msg_length,jump_length = decoder._DecodeVarint(file,0)
        jump_old = 0
        filelists = []
        while msg_length + jump_length <= len(file[jump_old:]):
            filelists.append(file[jump_old+jump_length : jump_old+msg_length+jump_length])
            jump_old = msg_length+jump_length + jump_old
            if jump_old != len(file):
                msg_length,jump_length = decoder._DecodeVarint(file[jump_old:],0)
        return filelists
  • 编写如下代码
import ruledb_pb2
    ConvertRule = self.urldedup_wraper.pb_convert(url_rule)
    ruledb = ruledb_pb2.UrlRule()
    for Rule in ConvertRule:
        ruledb.ParseFromString(Rule)
        print ruledb

#Python



你可能感兴趣的:(Python)