首页 > 代码库 > 照着例子学习protobuf-python

照着例子学习protobuf-python

以下是照着python操作protobuf进行的protobuf-python的学习笔记:

 

首先是protobuf的下载与安装:

1 由于google被墙,所以去github上面搜索了一下protobuf,于是找到了protobuf的git页:protobuf on github。

2 可以自己将protobuf下载下来进行编译,也可以直接用人家编译好的发行版,这个要看个人,我选择的是用编译好的发行版,下载地址在这里:protobuf realse version。

  记得要同时下载两个东西,例如我下载的是:protobuf-2.6.1.zip 和 protobuf-2.6.1-win32.zip。

  前者包含了protobuf与各语言(java,python)之间的protobuf运行时库,这个在转换的时候需要用到,相当与protobuf与各语言之间的协定格式。

  后者包含了一个文件 protoc.exe,编译工具来的。

3 由于我们是要学习protobuf-python来着,所以解压玩protobuf-2.6.1.zip之后,我们可以在文件夹下面找到一个python文件夹,在其中会看到一个setup.py。

  我们依次运行:python setup.py build 和 python setup.py install

  有没有成功在控制台可以看得到。

 

这样环境就安装好了(python 建议选择2.7版本)。

 

接着就是编写和转换proto文件:

1 新建一个addressbook.proto文件,这个文件完全是按照原帖编写的,如下:

package tutorial;message Person{	required string name = 1;	required int32 id = 2;	optional string email = 3;		enum PhoneType{		MOBILE = 0;		HOME = 1;		WORK = 2;	}		message PhoneNumber{		required string number = 1;		optional PhoneType type = 2[default = HOME];	}		repeated PhoneNumber phone = 4;}message AddressBook{	repeated Person person = 1;}

2 利用protoc.exe编译proto文件,如下:

其中 -I是源文件目录 --python_out是文件输出目录 最后的参数addressbook.proto是你需要编译的协议文件,

编译好之后你就会在目标目录里面看到输出的结果文件,如下:

  1 # Generated by the protocol buffer compiler.  DO NOT EDIT!  2 # source: addressbook.proto  3   4 import sys  5 _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode(latin1))  6 from google.protobuf import descriptor as _descriptor  7 from google.protobuf import message as _message  8 from google.protobuf import reflection as _reflection  9 from google.protobuf import symbol_database as _symbol_database 10 from google.protobuf import descriptor_pb2 11 # @@protoc_insertion_point(imports) 12  13 _sym_db = _symbol_database.Default() 14  15  16  17  18 DESCRIPTOR = _descriptor.FileDescriptor( 19   name=addressbook.proto, 20   package=tutorial, 21   serialized_pb=_b(\n\x11\x61\x64\x64ressbook.proto\x12\x08tutorial\"\xda\x01\n\x06Person\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\n\n\x02id\x18\x02 \x02(\x05\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12+\n\x05phone\x18\x04 \x03(\x0b\x32\x1c.tutorial.Person.PhoneNumber\x1aM\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x02(\t\x12.\n\x04type\x18\x02 \x01(\x0e\x32\x1a.tutorial.Person.PhoneType:\x04HOME\"+\n\tPhoneType\x12\n\n\x06MOBILE\x10\x00\x12\x08\n\x04HOME\x10\x01\x12\x08\n\x04WORK\x10\x02\"/\n\x0b\x41\x64\x64ressBook\x12 \n\x06person\x18\x01 \x03(\x0b\x32\x10.tutorial.Person) 22 ) 23 _sym_db.RegisterFileDescriptor(DESCRIPTOR) 24  25  26  27 _PERSON_PHONETYPE = _descriptor.EnumDescriptor( 28   name=PhoneType, 29   full_name=tutorial.Person.PhoneType, 30   filename=None, 31   file=DESCRIPTOR, 32   values=[ 33     _descriptor.EnumValueDescriptor( 34       name=MOBILE, index=0, number=0, 35       options=None, 36       type=None), 37     _descriptor.EnumValueDescriptor( 38       name=HOME, index=1, number=1, 39       options=None, 40       type=None), 41     _descriptor.EnumValueDescriptor( 42       name=WORK, index=2, number=2, 43       options=None, 44       type=None), 45   ], 46   containing_type=None, 47   options=None, 48   serialized_start=207, 49   serialized_end=250, 50 ) 51 _sym_db.RegisterEnumDescriptor(_PERSON_PHONETYPE) 52  53  54 _PERSON_PHONENUMBER = _descriptor.Descriptor( 55   name=PhoneNumber, 56   full_name=tutorial.Person.PhoneNumber, 57   filename=None, 58   file=DESCRIPTOR, 59   containing_type=None, 60   fields=[ 61     _descriptor.FieldDescriptor( 62       name=number, full_name=tutorial.Person.PhoneNumber.number, index=0, 63       number=1, type=9, cpp_type=9, label=2, 64       has_default_value=http://www.mamicode.com/False, default_value=_b("").decode(utf-8), 65       message_type=None, enum_type=None, containing_type=None, 66       is_extension=False, extension_scope=None, 67       options=None), 68     _descriptor.FieldDescriptor( 69       name=type, full_name=tutorial.Person.PhoneNumber.type, index=1, 70       number=2, type=14, cpp_type=8, label=1, 71       has_default_value=http://www.mamicode.com/True, default_value=1, 72       message_type=None, enum_type=None, containing_type=None, 73       is_extension=False, extension_scope=None, 74       options=None), 75   ], 76   extensions=[ 77   ], 78   nested_types=[], 79   enum_types=[ 80   ], 81   options=None, 82   is_extendable=False, 83   extension_ranges=[], 84   oneofs=[ 85   ], 86   serialized_start=128, 87   serialized_end=205, 88 ) 89  90 _PERSON = _descriptor.Descriptor( 91   name=Person, 92   full_name=tutorial.Person, 93   filename=None, 94   file=DESCRIPTOR, 95   containing_type=None, 96   fields=[ 97     _descriptor.FieldDescriptor( 98       name=name, full_name=tutorial.Person.name, index=0, 99       number=1, type=9, cpp_type=9, label=2,100       has_default_value=http://www.mamicode.com/False, default_value=_b("").decode(utf-8),101       message_type=None, enum_type=None, containing_type=None,102       is_extension=False, extension_scope=None,103       options=None),104     _descriptor.FieldDescriptor(105       name=id, full_name=tutorial.Person.id, index=1,106       number=2, type=5, cpp_type=1, label=2,107       has_default_value=http://www.mamicode.com/False, default_value=0,108       message_type=None, enum_type=None, containing_type=None,109       is_extension=False, extension_scope=None,110       options=None),111     _descriptor.FieldDescriptor(112       name=email, full_name=tutorial.Person.email, index=2,113       number=3, type=9, cpp_type=9, label=1,114       has_default_value=http://www.mamicode.com/False, default_value=_b("").decode(utf-8),115       message_type=None, enum_type=None, containing_type=None,116       is_extension=False, extension_scope=None,117       options=None),118     _descriptor.FieldDescriptor(119       name=phone, full_name=tutorial.Person.phone, index=3,120       number=4, type=11, cpp_type=10, label=3,121       has_default_value=http://www.mamicode.com/False, default_value=[],122       message_type=None, enum_type=None, containing_type=None,123       is_extension=False, extension_scope=None,124       options=None),125   ],126   extensions=[127   ],128   nested_types=[_PERSON_PHONENUMBER, ],129   enum_types=[130     _PERSON_PHONETYPE,131   ],132   options=None,133   is_extendable=False,134   extension_ranges=[],135   oneofs=[136   ],137   serialized_start=32,138   serialized_end=250,139 )140 141 142 _ADDRESSBOOK = _descriptor.Descriptor(143   name=AddressBook,144   full_name=tutorial.AddressBook,145   filename=None,146   file=DESCRIPTOR,147   containing_type=None,148   fields=[149     _descriptor.FieldDescriptor(150       name=person, full_name=tutorial.AddressBook.person, index=0,151       number=1, type=11, cpp_type=10, label=3,152       has_default_value=http://www.mamicode.com/False, default_value=[],153       message_type=None, enum_type=None, containing_type=None,154       is_extension=False, extension_scope=None,155       options=None),156   ],157   extensions=[158   ],159   nested_types=[],160   enum_types=[161   ],162   options=None,163   is_extendable=False,164   extension_ranges=[],165   oneofs=[166   ],167   serialized_start=252,168   serialized_end=299,169 )170 171 _PERSON_PHONENUMBER.fields_by_name[type].enum_type = _PERSON_PHONETYPE172 _PERSON_PHONENUMBER.containing_type = _PERSON173 _PERSON.fields_by_name[phone].message_type = _PERSON_PHONENUMBER174 _PERSON_PHONETYPE.containing_type = _PERSON175 _ADDRESSBOOK.fields_by_name[person].message_type = _PERSON176 DESCRIPTOR.message_types_by_name[Person] = _PERSON177 DESCRIPTOR.message_types_by_name[AddressBook] = _ADDRESSBOOK178 179 Person = _reflection.GeneratedProtocolMessageType(Person, (_message.Message,), dict(180 181   PhoneNumber = _reflection.GeneratedProtocolMessageType(PhoneNumber, (_message.Message,), dict(182     DESCRIPTOR = _PERSON_PHONENUMBER,183     __module__ = addressbook_pb2184     # @@protoc_insertion_point(class_scope:tutorial.Person.PhoneNumber)185     ))186   ,187   DESCRIPTOR = _PERSON,188   __module__ = addressbook_pb2189   # @@protoc_insertion_point(class_scope:tutorial.Person)190   ))191 _sym_db.RegisterMessage(Person)192 _sym_db.RegisterMessage(Person.PhoneNumber)193 194 AddressBook = _reflection.GeneratedProtocolMessageType(AddressBook, (_message.Message,), dict(195   DESCRIPTOR = _ADDRESSBOOK,196   __module__ = addressbook_pb2197   # @@protoc_insertion_point(class_scope:tutorial.AddressBook)198   ))199 _sym_db.RegisterMessage(AddressBook)200 201 202 # @@protoc_insertion_point(module_scope)
addressbook_pb2.py

 

然后我们就可以使用生成的python文件了,

1 首先新建一个程序文档,代码还是来自原帖的:

 1 import addressbook_pb2 2 import sys 3  4 def PromptForAddress(person): 5     person.id = int(raw_input("Please input the id of this person...")) 6     person.name = raw_input("Please input a name for the person...") 7     email = raw_input("Please enter the email address of the person....") 8  9     if email != "":10         person.email = email11         pass12 13     while True:14         number = raw_input("Enter a phone number :")15         if number == "":16             break17             pass18 19         phone_number = person.phone.add()20         phone_number.number = number21 22 23         type = raw_input("Is this a mobile, home, or work phone?")24         if type == "mobile":25             phone_number.type = addressbook_pb2.Person.MOBILE26         elif type == "home":27             phone_number.type = addressbook_pb2.Person.HOME28         elif type == "work":29             phone_number.type = addressbook_pb2.Person.WORK30         else:31             print("Unknown phont type; leaving as default value.")32             pass33         pass34     pass35 36 37 if len(sys.argv) != 2:38     print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE")39     sys.exit(-1)40     pass41 print("What am i doing....")42 address_book = addressbook_pb2.AddressBook()43 44 try:45     f = open(sys.argv[1], "rb")46     address_book.ParseFromString(f.read())47     f.close()48 except IOError, e:49     print(sys.argv[1] + " : File not found. Creating a new file")50     pass51 52 PromptForAddress(address_book.person.add())53 54 f = open(sys.argv[1], "wb")55 f.write(address_book.SerializeToString())56 f.close()
add_person.py

2 然后运行这个文件,并按照提示进行操作:

 

然后你就可以在你的文件夹下面发现了保存的beach文件。

 

照着例子学习protobuf-python