[英]Protobuf and Python: How to add messages to "repeatable Any" field?
I have a proto message:我有一个原始消息:
syntax = "proto3";
import "google/protobuf/any.proto";
message Task {
repeated google.protobuf.Any targets = 1;
// ...
}
message Target {
string name = 1;
// ...
}
How should I add Target messages into Task.targets
?我应该如何将 Target 消息添加到
Task.targets
?
In official docs I've found info about how to assign value to a single Any type value, however in my case I have repeated Any
field type.在官方文档中,我找到了有关如何为单个Any类型值赋值的信息,但是在我的情况下,我
repeated Any
字段类型。
Edit : Task.targets
may contain different types of targets, that's why Any
type is used.编辑:
Task.targets
可能包含不同类型的目标,这就是使用Any
类型的原因。 A single Target
message is just for minimal reproducible example.单个
Target
消息仅用于最小的可重现示例。
Thanks @Justin Schoen.谢谢@Justin Schoen。 According to https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Any , you need to first create an Any object, then Pack a Target (or any other object type) before appending it to the repeated list.
根据https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Any ,您需要先创建一个 Any 对象,然后打包一个 Target (或任何其他对象类型)在将其附加到重复列表之前。
from google.protobuf.any_pb2 import Any
task = Task()
target = Any()
target.Pack(Target())
task.targets.append(any)
After searching for an answer myself, I found this thread to be the most relevant so I'll post my solution here if it helps anyone (but in Java/Scala).在自己搜索答案后,我发现这个线程是最相关的,所以如果它对任何人有帮助,我会在这里发布我的解决方案(但在 Java/Scala 中)。
If you want如果你想
repeated google.protobuf.Any targets = 1;
and targets
can be any value such as (string, bool, int, etc). targets
可以是任何值,例如(string、bool、int 等)。 This is how I did it in scala/java:这就是我在 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()
I have limited knowledge of the any
type, but I would think it could be treated as if it were a repeated
list of Target
messages.我对
any
类型的了解有限,但我认为可以将其视为repeated
的Target
消息列表。
Python Code:蟒蛇代码:
task_targets = []
task_targets.append(<insert_pb2_import>.Target(name='test'))
return <insert_pb2_import>.Task(targets=task_targets)
After playing around some time I have decided to revise the solution that uses repeating Any.在玩了一段时间后,我决定修改使用重复 Any 的解决方案。 And here is an advice for those who got stuck in this same place: try to use specific types instead of
Any
.这里有一个给那些被困在同一个地方的人的建议:尝试使用特定类型而不是
Any
。
A workaround for my situation is to create messages of types SpecificTargetSet1
, SpecificTargetSet2
, etc., that contain specific targets.针对我的情况的解决方法是创建包含特定目标的
SpecificTargetSet1
、 SpecificTargetSet2
等类型的消息。 The Task
proto file would look like: Task
原型文件如下所示:
message Task {
google.protobuf.Any target_set = 1;
}
Target set proto file:目标集原型文件:
message SpecificTargetSet1 {
repeated SpecificTarget1 targets = 1;
}
And now a task could be created in such a way:现在可以通过以下方式创建任务:
target = Target()
target.name = "Some name"
target_set = SpecificTargetSet1()
target_set.targets.append(target)
task = Task()
task.target_set.Pack(target_set)
I do not mark my answer as correct, as it is just a workaround.我没有将我的答案标记为正确,因为这只是一种解决方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.