С файлом message.proto
сохраняется в папке proto
:
Я изменяю текущий рабочий каталог на папку proto
:
cd /test/proto
Затем я запускаю grpc_tools.protoc
, чтобы сгенерировать модуль Python protobuf:
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