照着例子学习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是你需要编译的协议文件,
编译好之后你就会在目标目录里面看到输出的结果文件,如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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=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=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=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=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=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=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=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_PHONETYPE 172 _PERSON_PHONENUMBER.containing_type = _PERSON 173 _PERSON.fields_by_name['phone'].message_type = _PERSON_PHONENUMBER 174 _PERSON_PHONETYPE.containing_type = _PERSON 175 _ADDRESSBOOK.fields_by_name['person'].message_type = _PERSON 176 DESCRIPTOR.message_types_by_name['Person'] = _PERSON 177 DESCRIPTOR.message_types_by_name['AddressBook'] = _ADDRESSBOOK 178 179 Person = _reflection.GeneratedProtocolMessageType('Person', (_message.Message,), dict( 180 181 PhoneNumber = _reflection.GeneratedProtocolMessageType('PhoneNumber', (_message.Message,), dict( 182 DESCRIPTOR = _PERSON_PHONENUMBER, 183 __module__ = 'addressbook_pb2' 184 # @@protoc_insertion_point(class_scope:tutorial.Person.PhoneNumber) 185 )) 186 , 187 DESCRIPTOR = _PERSON, 188 __module__ = 'addressbook_pb2' 189 # @@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_pb2' 197 # @@protoc_insertion_point(class_scope:tutorial.AddressBook) 198 )) 199 _sym_db.RegisterMessage(AddressBook) 200 201 202 # @@protoc_insertion_point(module_scope)
然后我们就可以使用生成的python文件了,
1 首先新建一个程序文档,代码还是来自原帖的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 = email 11 pass 12 13 while True: 14 number = raw_input("Enter a phone number :") 15 if number == "": 16 break 17 pass 18 19 phone_number = person.phone.add() 20 phone_number.number = number 21 22 23 type = raw_input("Is this a mobile, home, or work phone?") 24 if type == "mobile": 25 phone_number.type = addressbook_pb2.Person.MOBILE 26 elif type == "home": 27 phone_number.type = addressbook_pb2.Person.HOME 28 elif type == "work": 29 phone_number.type = addressbook_pb2.Person.WORK 30 else: 31 print("Unknown phont type; leaving as default value.") 32 pass 33 pass 34 pass 35 36 37 if len(sys.argv) != 2: 38 print("Usage:", sys.argv[0], "ADDRESS_BOOK_FILE") 39 sys.exit(-1) 40 pass 41 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 pass 51 52 PromptForAddress(address_book.person.add()) 53 54 f = open(sys.argv[1], "wb") 55 f.write(address_book.SerializeToString()) 56 f.close()
2 然后运行这个文件,并按照提示进行操作:
然后你就可以在你的文件夹下面发现了保存的beach文件。