以下是照着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=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 首先新建一个程序文档,代码还是来自原帖的:
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 然后运行这个文件,并按照提示进行操作: