Ken*_*tov 9 python protocol-buffers any
我有这样的.proto档案
syntax = "proto3";
import "google/protobuf/any.proto";
message Request {
google.protobuf.Any request_parameters = 1;
}
Run Code Online (Sandbox Code Playgroud)
如何创建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
Run Code Online (Sandbox Code Playgroud)
但是我有一个错误:
TypeError: Parameter to CopyFrom() must be instance of same class: expected google.protobuf.Any got dict.
Run Code Online (Sandbox Code Playgroud)
UPDATE
在提示@Kevin之后,我向.proto文件中添加了新消息:
message Small {
string a = 1;
}
Run Code Online (Sandbox Code Playgroud)
现在代码如下所示:
Request = ma_pb2.Request()
small = ma_pb2.Small()
small.a = "1"
some_any = Any()
some_any.Pack(small)
Request.request_parameters = small
Run Code Online (Sandbox Code Playgroud)
但在最后一次作业时我有一个错误:
Request.request_parameters = small
AttributeError: Assignment not allowed to field "request_parameters" in protocol message object.
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
Kev*_*vin 10
Any不是用于存储任意键和值的魔术盒.目的Any是表示"任何"消息类型,如果您可能不知道在运行时要使用哪条消息.但是在运行时,您仍需要记住一些特定的消息.然后,您可以使用.Pack()和.Unpack()方法,该消息转换为Any,并在这一点上,你会做类似的东西Request.request_parameters.CopyFrom(some_any).
所以,如果你想存储这个特定的字典:
{"a": 1, "b": 2}
Run Code Online (Sandbox Code Playgroud)
...你需要一个.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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4489 次 |
| 最近记录: |