【问题标题】:How to import protobuf module如何导入 protobuf 模块
【发布时间】:2019-03-25 18:31:38
【问题描述】:

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

【问题讨论】:

    标签: python protocol-buffers proto


    【解决方案1】:

    我认为您没有正确使用 Protobuf。腌制 Protobuf 毫无意义,因为 Protos 的全部意义在于它们是可序列化的。相反,您应该使用SerializeToStringParseFromString,如Protobuf docs here 中所述。

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

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

    【讨论】:

      猜你喜欢
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 2020-05-31
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      相关资源
      最近更新 更多