如何导入protobuf模块
How to import protobuf module
message.proto
文件保存在 proto
文件夹中:
我将当前工作目录更改为 proto
文件夹:
cd /test/proto
然后我运行宁grpc_tools.protoc
生成protobuf Python模块:
python -m grpc_tools.protoc -I. --python_out=. message.proto
message_pb2.py
生成成功:
script.py
位于上面的一个文件夹中,它包含:
from proto import message_pb2
message = message_pb2.Message(field_a = 'Monday')
print type(message)
当 运行 script.py
成功加载 message_pb2
模块并声明 Message
实例时:
<class 'message_pb2.Message'>
现在我想腌制消息对象,将两行附加到 script.py
:
import pickle
pickled = pickle.dumps(message)
这会引发 pickle.PicklingError
异常:
pickle.PicklingError: Can't pickle <class 'message_pb2.Message'>: it's not found as message_pb2.Message
稍后编辑
我在这里使用pickle
模块的原因是为了描述使用multiprocessing.queue
时发生的另一个问题。当我尝试使用 put
方法将 message
放入多处理 queue
时,会发生相同的 PicklingError
:
from multiprocessing import Queue
queue = Queue()
queue.put(message)
它导致同样的错误:
PicklingError: Can't pickle <class 'message_pb2.Message'>: import of module message_pb2 failed
如何解决这个问题?
有趣的是,如果我将生成的 message_pb2
Python 模块与 script.py
放在同一个文件夹中,问题就不会发生:
已修改 script.py
import message_pb2
message = message_pb2.Message(field_a = 'Monday')
from multiprocessing import Queue
queue = Queue()
queue.put(message)
解决方案:
使用SerializeToString
方法:
queue.put(message.SerializeToString())
msg = queue.get()
print msg.field_a
我认为您没有正确使用 Protobuf。腌制 Protobuf 没有意义,因为 Protos 的全部意义在于它们是可序列化的。相反,您应该使用 SerializeToString
和 ParseFromString
,如 Protobuf docs here.
中所述
正如他们在那里指出的那样,您将无法真正读取这些字符串,因为它们实际上只是为了方便而使用 str
的字节序列。
编辑:进一步研究,Protobufs 不可 pickle,详情请见此处:https://groups.google.com/forum/#!topic/protobuf/VqWJ3BmQXVg
message.proto
文件保存在 proto
文件夹中:
我将当前工作目录更改为 proto
文件夹:
cd /test/proto
然后我运行宁grpc_tools.protoc
生成protobuf Python模块:
python -m grpc_tools.protoc -I. --python_out=. message.proto
message_pb2.py
生成成功:
script.py
位于上面的一个文件夹中,它包含:
from proto import message_pb2
message = message_pb2.Message(field_a = 'Monday')
print type(message)
当 运行 script.py
成功加载 message_pb2
模块并声明 Message
实例时:
<class 'message_pb2.Message'>
现在我想腌制消息对象,将两行附加到 script.py
:
import pickle
pickled = pickle.dumps(message)
这会引发 pickle.PicklingError
异常:
pickle.PicklingError: Can't pickle <class 'message_pb2.Message'>: it's not found as message_pb2.Message
稍后编辑
我在这里使用pickle
模块的原因是为了描述使用multiprocessing.queue
时发生的另一个问题。当我尝试使用 put
方法将 message
放入多处理 queue
时,会发生相同的 PicklingError
:
from multiprocessing import Queue
queue = Queue()
queue.put(message)
它导致同样的错误:
PicklingError: Can't pickle <class 'message_pb2.Message'>: import of module message_pb2 failed
如何解决这个问题?
有趣的是,如果我将生成的 message_pb2
Python 模块与 script.py
放在同一个文件夹中,问题就不会发生:
已修改 script.py
import message_pb2
message = message_pb2.Message(field_a = 'Monday')
from multiprocessing import Queue
queue = Queue()
queue.put(message)
解决方案:
使用SerializeToString
方法:
queue.put(message.SerializeToString())
msg = queue.get()
print msg.field_a
我认为您没有正确使用 Protobuf。腌制 Protobuf 没有意义,因为 Protos 的全部意义在于它们是可序列化的。相反,您应该使用 SerializeToString
和 ParseFromString
,如 Protobuf docs here.
正如他们在那里指出的那样,您将无法真正读取这些字符串,因为它们实际上只是为了方便而使用 str
的字节序列。
编辑:进一步研究,Protobufs 不可 pickle,详情请见此处:https://groups.google.com/forum/#!topic/protobuf/VqWJ3BmQXVg