[英]Using google.protobuf.Any in python file
我有这样的.proto
文件
syntax = "proto3";
import "google/protobuf/any.proto";
message Request {
google.protobuf.Any request_parameters = 1;
}
如何创建Request
对象并填充其字段? 我试过这个:
import ma_pb2
from google.protobuf.any_pb2 import Any
parameters = {"a": 1, "b": 2}
Request = ma_pb2.Request()
some_any = Any()
some_any.CopyFrom(parameters)
Request.request_parameters = some_any
但是我有一个错误:
TypeError: Parameter to CopyFrom() must be instance of same class: expected google.protobuf.Any got dict.
UPDATE
在提示@Kevin后,我向.proto
文件添加了.proto
:
message Small {
string a = 1;
}
现在代码如下所示:
Request = ma_pb2.Request()
small = ma_pb2.Small()
small.a = "1"
some_any = Any()
some_any.Pack(small)
Request.request_parameters = small
但在最后一次作业时我有一个错误:
Request.request_parameters = small
AttributeError: Assignment not allowed to field "request_parameters" in protocol message object.
我做错了什么?
Any
不是用于存储任意键和值的魔术盒。 Any
的目的是表示“任何”消息类型 ,以防您在运行时可能不知道要使用哪条消息。 但是在运行时,您仍需要记住一些特定的消息。 然后,您可以使用.Pack()
和.Unpack()
方法将该消息转换为Any
, 此时您将执行类似Request.request_parameters.CopyFrom(some_any)
。
所以,如果你想存储这个特定的字典:
{"a": 1, "b": 2}
...你需要一个.proto
文件来描述一些包含名为a
和b
整数字段的消息类型。 就个人而言,我认为这有点过分; 只需将a
和b
字段直接放入Request
消息中,除非你有充分的理由将它们分开。 如果你“忘记”其中一个键, 你可以随时添加它 ,所以不要过于担心完整性。
如果你真的想要一个“用于存储任意键和值的魔术盒”,而不是我上面描述的,你可以使用Map而不是Any
。 这样做的好处是,在密钥集可能包含任意字符串(例如,HTTP标头)的情况下,不要求您预先声明所有密钥。 它的缺点是难以进行lint或类型检查(特别是在静态类型语言中),因为你可以比一个属性更容易拼错一个字符串。 如链接资源中所示,映射基本上是重复字段的语法糖,如下所示(也就是说,线上表示与您执行此操作时所获得的完全相同,因此它向后兼容客户端不支持地图):
message MapFieldEntry {
key_type key = 1;
value_type value = 2;
}
repeated MapFieldEntry map_field = N;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.