[英]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.