将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
时发生的另一个问题。当我尝试使用PicklingError
方法将message
放入多处理queue
时,会发生相同的put
:
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
答案 0 :(得分:1)
我认为您没有正确使用Protobuf。腌制Protobuf毫无意义,因为Protos的全部意义在于它们是可序列化的。相反,您应该使用Protobuf docs here中所述的SerializeToString
和ParseFromString
。
正如他们在此处指出的那样,您将无法真正读取这些字符串,因为它们实际上只是为了方便起见而使用str
的字节序列。
编辑:仔细研究一下,Protobufs不能腌制,请参见此处了解更多详细信息:https://groups.google.com/forum/#!topic/protobuf/VqWJ3BmQXVg