Python 协议缓冲区中是否有映射字段的复制构造函数?

Jac*_*ack 5 python protocol-buffers

Python Generated Code解释了Python中 protobuf映射字段的大多数用例,但没有解释如何将一个映射复制到另一个映射。

给定简单地图

message Src {
    map<string, string> properties = 1;
    ...
}

message Dst {
    map<string, string> properties = 1;
    ...
}
Run Code Online (Sandbox Code Playgroud)

您无法为嵌入的消息字段分配值,因此无需执行以下操作:

# Will not work.
dst = Dst()
dst.properties = src.properties
Run Code Online (Sandbox Code Playgroud)

也没有CopyFrom的实现,因为 map 本身不是一条消息,它是消息中的一个字段。

# Will not work.
dst = Dst()
dst.properties.CopyFrom(src.properties)
Run Code Online (Sandbox Code Playgroud)

我也无法复制整个消息,因为我只想要地图。

# Copies unwanted fields!
dst = Dst()
dst.CopyFrom(src)
Run Code Online (Sandbox Code Playgroud)

我希望我不必遍历所有键并一一分配!

# Iterate over map keys
for key in src.properties:
    dst.properties[key] = src.properties[key]
Run Code Online (Sandbox Code Playgroud)

kri*_*ina 3

如果地图的值是简单类型,dst.properties.update(src.properties)应该可以工作。但是,如果您有一个包含消息类型值的映射,例如:

message Prop {
  optional string value = 1;
  optional bool is_public = 2;
}

message Src {
    map<string, Prop> properties = 1;
    ...
}

message Dst {
    map<string, Prop> properties = 1;
    ...
}
Run Code Online (Sandbox Code Playgroud)

那么.update(或任何类型的直接赋值)将抛出:

ValueError: Direct assignment of submessage not allowed
Run Code Online (Sandbox Code Playgroud)

相反,您必须执行以下操作:

for k, v in src.properties.items():
  dst.properties[k].CopyFrom(v)
Run Code Online (Sandbox Code Playgroud)