Accéder champ de Protobuf message de type inconnu en Python

Disons que j'ai 2 Protobuf-Messages, A et B. l'ensemble de Leur structure est similaire, mais pas identique. Nous sommes donc partagés choses dans un autre message, que nous avons appelé des Communes. Cela fonctionne à merveille.

Cependant, je suis maintenant face au problème suivant: Un cas particulier existe où je dois traiter un message avec numéro de série, mais je ne sais pas si c'est un message de type A ou de type B. j'ai une solution qui fonctionne en C++ (voir ci-dessous), mais je n'ai pas réussi à trouver un moyen de faire la même chose en Python.

Exemple:

//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 ...
}

Solution de travail en C++

En C++, je suis en utilisant l'API reflection pour obtenir l'accès à la CommonSettings champ comme ceci:

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));
}

La méthode 'getCommonBlock' utilise FindFieldByNumber() pour obtenir le descripteur de champ que j'essaie de faire. Ensuite, il utilise la réflexion pour récupérer les données réelles. getCommonBlock peut traiter des messages de type A, B ou dans tout autre type de longtemps que le champ Commun demeure située à l'indice 3.

Ma Question est: Est-il un moyen de faire quelque chose de similaire Python? J'ai été à la recherche à la Protobuf documentation, mais ne pouvait pas trouver un moyen de le faire.

OriginalL'auteur djf | 2013-05-17