将序列化的 protobuf 输出转换为 python 字典

Ash*_*mar 5 python json dictionary protocol-buffers

给定一个字符串格式的序列化 protobuf(协议缓冲区)输出。我想把它转换成Python字典。

假设这是序列化的 protobuf,以 python 字符串形式给出:

person {
  info {
    name: John
    age: 20
    website: "https://mywebsite.com"
    eligible: True
  }
}
Run Code Online (Sandbox Code Playgroud)

我想将上面的 python 字符串转换为 python 字典data,如下所示:

person {
  info {
    name: John
    age: 20
    website: "https://mywebsite.com"
    eligible: True
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以编写一个 python 脚本来进行转换,如下所示:

  • 在不以大括号结尾的每一行添加逗号。
  • 在左大括号前添加一个额外的冒号。
  • 用引号将每个单独的键和值对括起来。
  • 最后使用该json.loads()方法将其转换为Python字典。

我想知道是否可以使用协议缓冲区中已有的更简单或标准方法来实现这种转换。那么,除了使用我上面提到的步骤手动编写脚本之外,是否有更好的或标准的方法可用于将序列化的 protobuf 输出转换为 python 字典?

ayd*_*dow 2

你可以使用proto的Message类。

In [6]: import proto

In [7]: curr
Out[7]:
campaign {
  resource_name: "customers/1234/campaigns/5678"
  id: 9876
  name: "testing 1, 2, 3"
  advertising_channel_type: SEARCH
}
landing_page_view {
  resource_name: "customers/1234/landingPageViews/1234567890"
  unexpanded_final_url: "https://www.example.com/"
}

In [8]: proto.Message.to_dict(
   ...:     curr,
   ...:     use_integers_for_enums=False,
   ...:     including_default_value_fields=False,
   ...:     preserving_proto_field_name=True
   ...: )
Out[8]:
{'campaign': {'resource_name': 'customers/1234/campaigns/5678',
  'advertising_channel_type': 'SEARCH',
  'name': 'testing 1, 2, 3',
  'id': '9876'},
 'landing_page_view': {'resource_name': 'customers/1234/landingPageViews/1234567890',
  'unexpanded_final_url': 'https://www.example.com/'}}
Run Code Online (Sandbox Code Playgroud)

请注意,在 中to_dict,所有 kwargs 默认为True.

如果您只想to_json立即序列化消息而不必使用json.dumps.

还值得注意的一个警告是该proto包最近的内存泄漏。该线程表示已发布修复程序,但我在较大数据集上使用它时的经验表明并非如此。仅仅因为某些东西在本地工作,并不意味着您将其部署到的容器可以处理相同的负载。