簡體   English   中英

在python文件中使用google.protobuf.Any

[英]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文件來描述一些包含名為ab整數字段的消息類型。 就個人而言,我認為這有點過分; 只需將ab字段直接放入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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM