J'ai un message proto:
syntax = "proto3"; import "google/protobuf/any.proto"; message Task { repeated google.protobuf.Any targets = 1; // ... } message Target { string name = 1; // ... }
Comment puis-je ajouter des messages Target dans Task.targets
?
Dans la documentation officielle I ' J'ai trouvé des informations sur la façon d'attribuer une valeur à un seul Tout une valeur de type>, mais dans mon cas, j'ai répété le type de champ Any
.
Modifier : Task.targets
peut contenir différents types de cibles, c'est pourquoi le type Any
est utilisé. Un seul message Target
est juste pour un exemple reproductible minimal.
4 Réponses :
J'ai une connaissance limitée du type any
, mais je pense que cela pourrait être traité comme s'il s'agissait d'une liste répétée
de Target
messages.
Code Python:
task_targets = [] task_targets.append(<insert_pb2_import>.Target(name='test')) return <insert_pb2_import>.Task(targets=task_targets)
Un test simple donne une erreur: TypeError: Le paramètre de MergeFrom () doit être une instance de la même classe: google.protobuf.Any got Target
Il semble que vous deviez initialiser votre tableau Any
, puis utiliser la méthode pack
pour y ajouter des éléments. vérifiez ceci
Après avoir joué pendant un certain temps, j'ai décidé de réviser la solution qui utilise la répétition de Any. Et voici un conseil pour ceux qui sont restés coincés au même endroit:
essayez d'utiliser des types spécifiques au lieu de Any
.
Une solution de contournement pour ma situation consiste à créer des messages de types SpecificTargetSet1
, SpecificTargetSet2
, etc. , qui contiennent des cibles spécifiques. Le fichier proto Task
ressemblerait à:
target = Target() target.name = "Some name" target_set = SpecificTargetSet1() target_set.targets.append(target) task = Task() task.target_set.Pack(target_set)
Fichier proto de l'ensemble cible:
message SpecificTargetSet1 { repeated SpecificTarget1 targets = 1; }
Et maintenant, une tâche pourrait être créée de cette manière:
message Task { google.protobuf.Any target_set = 1; }
Je ne marque pas ma réponse comme correcte, car il ne s'agit que d'une solution de contournement.
Merci @Justin Schoen. Selon https://developers.google. com / protocol-buffers / docs / reference / java / com / google / protobuf / Any , vous devez d'abord créer un objet Any, puis Pack a Target (ou tout autre type d'objet) avant de l'ajouter au liste.
from google.protobuf.any_pb2 import Any task = Task() target = Any() target.Pack(Target()) task.targets.append(any)
Après avoir cherché moi-même une réponse, j'ai trouvé ce fil de discussion le plus pertinent, je publierai donc ma solution ici si cela aide quelqu'un (mais en Java / Scala).
Si vous le souhaitez
XXX
et cibles
peuvent être n'importe quelle valeur telle que (string, bool, int, etc.). Voici comment je l'ai fait dans scala / java:
val task = Task.newBuilder() .addTargets(Any.pack(StringValue.of("iss"))) .addTargets(Any.pack(Int32Value.of(25544))) .addTargets(Any.pack(DoubleValue.of(1004.882447947814))) .addTargets(Any.pack(DoubleValue.of(84.90917890132))) .addTargets(Any.pack(DoubleValue.of(14.620929684))) .addTargets(Any.pack(StringValue.of("kilometers"))) .build()