繁体   English   中英

如何导入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问题:

在此处输入图片说明

修改后的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的全部意义在于它们是可序列化的。 相反,您应该按照Protobuf文档中的说明使用SerializeToStringParseFromString

正如他们在此处指出的那样,您将无法实际读取这些字符串,因为它们实际上只是为了方便起见使用str的字节序列。

编辑:进一步研究,Protobufs不能腌制,请参见此处以了解更多详细信息: https : //groups.google.com/forum/#!topic/ protobuf/VqWJ3BmQXVg

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM