protobuf与json转换小结

protobuf与json转换小结是一个比较常见的问题,在这里我将为你提供一个完整的攻略。

什么是protobuf

Protobuf(Protocol Buffers)是Google开发的一种轻便、高效、通用的数据序列化格式,可以用于数据存储、RPC(Remote procedure call)和数据交换等领域。它与XML和JSON等其他序列化格式相比,更为紧凑、快速,而且具有更好的性能。

在使用Protobuf前,需要定义一个.proto文件,该文件定义了要序列化的数据结构和数据类型。在定义好.proto文件的所有内容后,通过利用ProtoBuf中的编译器生成所需的数据对应的代码,进而在代码中调用对应接口进行数据序列化和反序列话操作。

protobuf与json之间的转换

Protobuf和JSON之间的转换非常常见,下面是protobuf和JSON之间转换的两种方式:

第一种方式:使用protobuf自带的JsonFormat工具

protobuf在自己的库中提供了JsonFormat工具,可以在protobuf和JSON之间进行转换,下面是转换的示例:

定义.proto文件

syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;  // Unique ID number for this person.
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

生成对应的数据结构

通过proto文件生成对应的数据结构:

protoc --proto_path=. --python_out=. ./person.proto

生成person_pb2.py文件,包含了所有protobuf数据对应的Python类

protobuf数据序列化为JSON字符串

import json
from google.protobuf.json_format import MessageToJson
from tutorial.person_pb2 import Person, PhoneNumber

def protobuf_to_json():
  person = Person()
  person.name = "John Doe"
  person.id = 1234
  person.email = "jdoe@example.com"
  phone = PhoneNumber()
  phone.number = "555-4321"
  phone.type = Person.HOME
  person.phones.append(phone)

  # 将protobuf数据转换为JSON字符串
  json_str = MessageToJson(person)
  print(json_str)

执行代码生成的JSON字符串为:

{
  "name": "John Doe",
  "id": 1234,
  "email": "jdoe@example.com",
  "phones": [
    {
      "number": "555-4321",
      "type": "HOME"
    }
  ]
}

JSON字符串反序列化为protobuf数据

def json_to_protobuf():
  json_str = """
  {
    "name": "John Doe",
    "id": 1234,
    "email": "jdoe@example.com",
    "phones": [
      {
        "number": "555-4321",
        "type": "HOME"
      }
    ]
  }
  """

  # 将JSON字符串转换为protobuf数据
  person = Person()
  json_format.Parse(json_str, person)
  print(person.name, person.id, person.email, person.phones[0].number, person.phones[0].type)

第二种方式:手动转换

不使用protobuf自带的工具,而是使用Python中自带的json库、protobuf库中自带的编码和解码方法手动转换。下面是手动转换的示例:

protobuf数据序列化为JSON字符串

def protobuf_to_json2():
  person = Person()
  person.name = "John Doe"
  person.id = 1234
  person.email = "jdoe@example.com"
  phone = PhoneNumber()
  phone.number = "555-4321"
  phone.type = Person.HOME
  person.phones.append(phone)

  # 手动序列化:protobuf数据转换为Python字典
  person_dict = {
    "name": person.name,
    "id": person.id,
    "email": person.email,
    "phones": [{
      "number": p.number,
      "type": p.type
    } for p in person.phones]
  }

  # 将Python字典转换为JSON字符串
  json_str = json.dumps(person_dict, indent=2)
  print(json_str)

执行代码生成的JSON字符串为:

{
  "name": "John Doe",
  "id": 1234,
  "email": "jdoe@example.com",
  "phones": [
    {
      "number": "555-4321",
      "type": "HOME"
    }
  ]
}

JSON字符串反序列化为protobuf数据

def json_to_protobuf2():
  json_str = """
  {
    "name": "John Doe",
    "id": 1234,
    "email": "jdoe@example.com",
    "phones": [
      {
        "number": "555-4321",
        "type": "HOME"
      }
    ]
  }
  """

  # 将JSON字符串转换为Python字典
  person_dict = json.loads(json_str)

  # 手动反序列化:Python字典转换为protobuf数据
  person = Person()
  person.name = person_dict["name"]
  person.id = person_dict["id"]
  person.email = person_dict["email"]
  for phone_dict in person_dict["phones"]:
    phone = person.phones.add()
    phone.number = phone_dict["number"]
    phone.type = getattr(Person.PhoneType, phone_dict["type"])

  print(person.name, person.id, person.email, person.phones[0].number, person.phones[0].type)

总结

以上就是protobuf和JSON之间转换的两种方式。如果你了解了protobuf文件的定义和Python中使用Protobuf的基本知识,在protobuf和JSON之间进行转换并不会是一件难事。哪个转换方式更好,需要根据实际情况来选择,这里的示例只是展示了两种基本的转换方法,具体的应用需要根据实际情况进行选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:protobuf与json转换小结 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • java中PriorityBlockingQueue的入队知识点总结

    下面是对 “java中PriorityBlockingQueue的入队知识点总结” 的详细讲解。 PriorityBlockingQueue的概述 PriorityBlockingQueue 是 java.util.concurrent 包中的一个类,它是一个具有优先级的无界阻塞队列,可以用来实现生产者-消费者模式中的队列。 PriorityBlocking…

    Java 2023年5月26日
    00
  • Vue之前端体系与前后端分离详解

    Vue之前端体系与前后端分离详解 什么是前后端分离? 前后端分离是一个架构模式,将Web应用程序的整体解耦成逻辑上独立的前端和后端两部分。在前后端分离的架构模式下,前端负责呈现页面/表现层,后端负责处理业务逻辑/数据层。 前后端分离的好处: 前后端团队分工明确,互不干扰 明确的API接口文档,方便开发和测试 前后端分别使用合适的技术栈,方便维护和升级 Vue…

    Java 2023年5月23日
    00
  • Spring Security基本架构与初始化操作流程详解

    Spring Security基本架构与初始化操作流程详解 什么是Spring Security Spring Security是一个基于Spring框架的安全解决方案,主要解决应用程序的认证和授权问题。它提供了一整套安全服务,并可在Web请求级和方法调用级处理身份验证和授权。 Spring Security基本架构 Spring Security的基本架构…

    Java 2023年5月20日
    00
  • Java日期处理工具类DateUtils详解

    Java日期处理工具类DateUtils详解 在Java开发中,处理日期时间相关的操作是非常常见的需求。Java提供了许多DateTime API来完成这些任务,其中常用的就是java.util.Date和java.util.Calendar。而apache提供的DateUtils工具类,则对日期的操作进行了更多的封装,使得开发人员更加方便和便捷地进行日期的…

    Java 2023年5月20日
    00
  • Struts2框架初学接触

    Struts2框架初学接触攻略 简介 Struts2是一款基于MVC设计模式的Web应用框架,可以帮助开发者快速创建可维护、可扩展的Web应用程序。使用Struts2可以将应用程序的业务逻辑与表示层(视图)分离,使得程序更易于维护和扩展。本文将为初学者介绍如何使用Struts2开发Web应用程序。 步骤 以下是使用Struts2框架开发Web应用程序的步骤:…

    Java 2023年5月20日
    00
  • Java中的ArrayList容量及扩容方式

    下面我将为您详细讲解Java中的ArrayList容量及扩容方式的完整攻略。 概述 ArrayList是Java集合框架中的一种常用容器,它可以动态地增长和缩小。在往ArrayList中添加元素时,程序可以不必关心容量问题,ArrayList会自动管理容量。 容量 ArrayList底层是用数组实现的,我们可以通过capacity()方法获得ArrayLis…

    Java 2023年5月26日
    00
  • Spring MVC拦截器的基本使用方法

    Spring MVC拦截器的基本使用方法 在 Spring MVC 中,拦截器是一种非常有用的机制,可以在请求到达控制器之前或之后执行一些操作。本文将详细讲解 Spring MVC 拦截器的基本使用方法,包括如何创建拦截器、如何配置拦截器、如何使用拦截器等。 创建拦截器 在 Spring MVC 中,我们可以通过实现 HandlerInterceptor 接…

    Java 2023年5月18日
    00
  • MySQL为例讲解JDBC数据库连接步骤

    MySQL为例讲解JDBC数据库连接步骤 JDBC简介 JDBC(Java Database Connectivity)是一种Java语言中访问数据库的API(Application Programming Interface)。 JDBC可以让Java程序连接到各种关系型数据库,进行数据的读取、写入操作等。JDBC的设计目标是使Java程序员从不同的关系型…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部