Предположим, у меня есть 2 Protobuf-сообщения, A и B. Их общая структура похожа, но не идентична. Поэтому мы переместили общий материал в отдельное сообщение, которое мы назвали Common. Это прекрасно работает.Доступ к полю сообщения Protobuf неизвестного типа в Python
Однако я столкнулся со следующей проблемой: существует специальный случай, когда мне приходится обрабатывать сериализованное сообщение, но я не знаю, является ли это сообщением типа A или типа B. У меня есть рабочее решение в C++ (показано ниже), но мне не удалось найти способ сделать то же самое в Python.
Пример:
// file: Common.proto
// contains some kind of shared struct that is used by all messages:
message Common {
...
}
// file: A.proto
import "Common.proto";
message A {
required int32 FormatVersion = 1;
optional bool SomeFlag [default = true] = 2;
optional Common CommonSettings = 3;
... A-specific Fields ...
}
// file: B.proto
import "Common.proto";
message B {
required int32 FormatVersion = 1;
optional bool SomeFlag [default = true] = 2;
optional Common CommonSettings = 3;
... B-specific Fields ...
}
Рабочий раствор в C++
В C++ Я использую Reflection API, чтобы получить доступ к полю CommonSettings так:
namespace gp = google::protobuf;
...
Common* getCommonBlock(gp::Message* paMessage)
{
gp::Message* paMessage = new gp::Message();
gp::FieldDescriptor* paFieldDescriptor = paMessage->GetDescriptor()->FindFieldByNumber(3);
gp::Reflection* paReflection = paMessage->GetReflection();
return dynamic_cast<Common&>(paReflection->GetMessage(*paMessage,paFieldDescriptor));
}
Метод 'getCommonBlock' us es FindFieldByNumber(), чтобы получить дескриптор поля, которое я пытаюсь получить. Затем он использует отражение для получения фактических данных. getCommonBlock может обрабатывать сообщения типа A, B или любого будущего типа, если общее поле остается в индексе 3.
Мой вопрос: есть ли способ сделать аналогичную вещь Python? Я смотрел на Protobuf documentation, но не мог понять, как это сделать.
Это сработало бы, если бы у меня был экземпляр obj. Может быть, мне нужно немного разъяснить мою проблему: я получаю сообщение - в типичной форме protobuf - как сериализованный blob (поток двоичной памяти). Как я могу создать экземпляр obj из этого, не зная тип базового сообщения? – djf