Python读取及生成pb文件,pb与jsonStr互转,pb与dictJson互转,打包.exe/.sh并转换,很完美跨平台

news2024/12/27 14:45:43

Python读取及生成pb文件,pb与jsonStr互转,pb与dictJson互转,打包.exe/.sh并转换,很完美跨平台

    • 1. 效果图
    • 2. 命令行:proto文件转.class(绝对路径或相对路径)
    • 3. 序列化、反序列化api
    • 4. pb转json,json转pb,pb转dict
    • 5. 打包.exe/.sh并调用
    • 6. 源代码
      • 6.1 addressbook.proto
      • 6.2 pb2json.py
    • 参考

  1. 读取pb及生成pb文件
  2. pb文件转jsonString
  3. 二进制pb转jsonString
  4. 二进制pb转jsonDict
  5. jsonString转pb
  6. jsonDict转pb
  7. 赋值(有空或者类型不对应会无法赋值及报错)
  8. 打包exe/sh

1. 效果图

读取pb文件并解析为jsonStr打印
在这里插入图片描述

2. 命令行:proto文件转.class(绝对路径或相对路径)

d:
cd D:\study\python-scripts\p20230731\pb2json
protoc -I=D:\study\python-scripts\p20230731\pb2json\ --python_out=D:\study\python-scripts\p20230731\pb2json\ D:\study\python-scripts\p20230731\pb2json\addressbook.proto

d:
cd D:\study\python-scripts\p20230731\pb2json
protoc -I=. --python_out=./ ./addressbook.proto

效果图如下:

在这里插入图片描述

执行成功后会在本地生成: addressbook_pb2.py
在这里插入图片描述
Java 和 Python不一致的地方,Java可以指定包名,类名(.proto名称可以随意);会自适应生成相应的JavaPB对象
Python可以指定包名,不指定类名(.proto名称固定),默认为 aaa.proto 则生成 aaa_pb2.py类

在这里插入图片描述

3. 序列化、反序列化api

  • IsInitialized():检查是否已设置所有必填字段。
  • str():返回消息的人类可读表示形式, 对于调试特别有用。(通常调用为 str(message) 或 print message.)
  • CopyFrom(other_msg):用给定消息的值。
  • Clear():将所有元素清除回空状态。

协议缓冲区类有用于写入和读取消息的方法 使用协议缓冲区的所选类型 二进制格式 。这些 包括:

  • SerializeToString():序列化消息并将其作为字符串返回。 请注意,字节是二进制的,而不是文本的;我们只使用 str 键入为 方便的容器。
  • ParseFromString(data):从给定字符串解析消息

4. pb转json,json转pb,pb转dict

google.protobuf.json_format
https://googleapis.dev/python/protobuf/latest/google/protobuf/json_format.html

5. 打包.exe/.sh并调用

windows下到打包

pyinstaller pb2json.py

上边的语句可能会报错: Error loading Python DLL
‘C:\Users\ADMINI~1\AppData\Local\Temp_MEI41642\python310.dll’
LoadLibrary:找不到指定的模块。

用下边的语句ok:

pyinstaller --onefile pb2json.py

linux平台打包则得到可在linux平台运行的二进制可执行文件

6. 源代码

6.1 addressbook.proto

syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;

  enum PhoneType {
    PHONE_TYPE_UNSPECIFIED = 0;
    PHONE_TYPE_MOBILE = 1;
    PHONE_TYPE_HOME = 2;
    PHONE_TYPE_WORK = 3;
  }

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

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

6.2 pb2json.py

#!/usr/bin/env python3
import json
import sys

from google.protobuf import json_format

import addressbook_pb2

if len(sys.argv) == 2:
    print("Usage:", sys.argv[0], sys.argv[1], "address_file")
    print('--------------------------------------------------------')
    pb_path = sys.argv[1]
    address = addressbook_pb2.AddressBook()

    # 从已经存在的文件读取pb
    try:
        with open(pb_path, "rb") as f:
            address.ParseFromString(f.read())
    except IOError:
        print(pb_path + ": Could not open file...")

    # pb转json
    json_string = json_format.MessageToJson(address)
    print('json_string: ', json_string)
    print('--------------------------------------------------------')



address_book = addressbook_pb2.AddressBook()
# person = addressbook_pb2.Person() # 初始化方式1
person = address_book.people.add()  # 初始化方式2
person.id = 1234
person.name = "John Doe"
person.email = "jdoe@example.com"
phone = person.phones.add()
phone.number = "555-4321"
phone.type = addressbook_pb2.Person.PHONE_TYPE_HOME

person2 = address_book.people.add()  # 初始化方式2
person2.id = 1314
person2.name = "Lucy"
person2.email = "Lucy@example.com"
phone2 = person2.phones.add()
phone2.number = "010-4321"
phone2.type = addressbook_pb2.Person.PHONE_TYPE_WORK

# 请注意,这些赋值不仅仅是向 通用 Python 对象。如果要尝试分配未定义的字段 在 .proto 文件,一个 AttributeError 会被提出来。
# 如果分配字段 对于错误类型的值,a TypeError 将被提出。另外,阅读 字段在设置之前的值将返回默认值。
try:
    person.no_such_field = 1  # raises AttributeError
    person.id = "1234"  # raises TypeError
except AttributeError as e:
    print('AttributeError:', e)
except TypeError as e:
    print('TypeError:', e)

try:
    person.id = "1234"  # raises TypeError
except TypeError as e:
    print('TypeError:', e)

# 序列化以string返回
str = address_book.SerializeToString()
print('str: ', str)

# 从文件读取pb,并打印所有属性
pb_path = 'addressbook.pb'

with open(pb_path, 'wb') as f:
    f.write(str)


# 遍历所有的字段及对象属性
def ListPeople(address_book):
    for person in address_book.people:
        print("Person ID:", person.id)
        print("  Name:", person.name)
        if person.email is not None:
            print("  E-mail address:", person.email)

        for phone_number in person.phones:
            if phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_MOBILE:
                print("  Mobile phone #: ", end="")
            elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_HOME:
                print("  Home phone #: ", end="")
            elif phone_number.type == addressbook_pb2.Person.PhoneType.PHONE_TYPE_WORK:
                print("  Work phone #: ", end="")
            print(phone_number.number)


address_book = addressbook_pb2.AddressBook()

# 读取已经存在的文件
with open(pb_path, "rb") as f:
    address_book.ParseFromString(f.read())

# 遍历打印所有属性
ListPeople(address_book)

# pb转json
json_string = json_format.MessageToJson(address_book)
print('pb2json_string: ', json_string)

pb_json_path = pb_path.replace(".pb", "_pb.json")
with open(pb_json_path, 'w') as f:
    f.write(json_string)

# json_str 转pb对象
address2 = addressbook_pb2.AddressBook()
json_format.Parse(json_string,address2)
print('json_str2pb: ',address2)

# pb转dict
json_dict = json_format.MessageToDict(address_book)
print("pb2json_dict: ", json_dict)

pb_dict_path = pb_path.replace(".pb", "_pb_dict.json")
with open(pb_dict_path, 'w') as f:
    f.write(json.dumps(json_dict))

# json_dict 转pb
address3 = addressbook_pb2.AddressBook()
json_format.Parse(json_string,address3)
print('json_dict2pb: ',address3)

参考

  • https://protobuf.dev/getting-started/pythontutorial/
  • https://googleapis.dev/python/protobuf/latest/google/protobuf/json_format.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/840736.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建MyBatis开发环境

hi,大家好,今天来学习一下MyBatis的相关知识 文章目录 🧊1.MyBatis定义🧊2.为什么要学习MyBatis🧊3.搭建MyBatis开发环境🍐3.1前置工作--创建数据库和表🍐3.2在新项目中添加MyBatis的框架🍐3.3设置MyBatis…

Leetcode31 下一个排列

解题思路: 算法过程的第二步,可以变为将[j,end]排序,然后从[j,end)和i进行比较,在区间j,end区间第一个大于nums[i]后,交换即可 public void nextPermutation(int[] nums) {int len nums.length - 1;for(int i len;i…

小程序的 weiui的使用以及引入

https://wechat-miniprogram.github.io/weui/docs/quickstart.html 网址 1.点进去,在app.json里面配置 在你需要的 页面的 json里面配置,按需引入 然后看文档,再在你的 wxml里面使用就好了

使用DMA传输实现单片机高效串口转发——以STM32系列为例

使用DMA传输实现单片机高效串口转发——以STM32系列为例 DateAuthorVersionNote2023.08.06Dog TaoV1.01. 完成了文档的撰写。 文章目录 使用DMA传输实现单片机高效串口转发——以STM32系列为例应用场景实现流程源码示例串口与中断配置DMA外设配置DMA发送数据函数串口中断服务函…

Java中String方法魔性学习

这里写目录标题 先进行专栏介绍String详解常用构造方法代码演示常用成员方法代码示例总结 先进行专栏介绍 本专栏是自己学Java的旅途,纯手敲的代码,自己跟着黑马课程学习的,并加入一些自己的理解,对代码和笔记 进行适当修改。希望…

【redis】SpringBoot集成redis

目录 1.添加redis依赖2.配置redis3.操作redis3.1 操作string 3.1 操作其它数据类型 4. Spring-Session基于Redis解决共享Session问题4.1 问题提出 4.1 添加依赖 4.2 修改配置4.3 存储和读取 1.添加redis依赖 方法①&#xff1a; <dependency><groupId>org.springf…

ChatGPT已闯入学术界,Elsevier推出AI工具

2022年11月&#xff0c;OpenAI公司发布了ChatGPT&#xff0c;这是迄今为止人工智能在现实世界中最重要的应用之一。 当前&#xff0c;互联网搜索引擎中出现了越来越多的人工智能&#xff08;AI&#xff09;聊天机器人&#xff0c;例如谷歌的Bard和微软的Bing&#xff0c;看起来…

微信小游戏流量主结算财务信息填写指引

微信小游戏个人开发者: 流量主结算财务信息填写指南 一,登录公众平台二,补充财务信息三,补充信息指引四,提交审核五,绑定通知对于微信小游戏个人开发者来说,流量主结算财务信息的填写是非常重要的一步。正确填写可以保证收入的及时结算,而填写不当则可能会导致收入无法到…

wxRibbonBar 常用三种控件Button,DropdownButton,HybridButton

这三种控件的效果如下所示&#xff1a; 点击下拉的效果&#xff1a; 这一部分可以设置wxITEM_CHECK&#xff0c;wxITEM_RADIO等效果 但我们可能更关注实现实例&#xff1a; &#xff08;1&#xff09;MyFrame.h #pragma once #include <wx/wx.h> #include "wx/wx…

vue2-diff算法

1、diff算法是什么&#xff1f; diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点&#xff1a; 比较只会在同层级进行&#xff0c;不会跨层级进行。 在diff比较的过程中&#xff0c;循环从两边向中间比较。 diff算法在很多场景中都有应用&#xff0c;在vue中&…

(学习笔记-进程管理)进程

进程 我们编写的代码只是一个存储在硬盘的静态文件&#xff0c;通过编译后会生成二进制可执行文件&#xff0c;当我们运行这个可执行文件后&#xff0c;它会被装载到内存中&#xff0c;接着CPU会执行程序中的每一条指令&#xff0c;那么这个运行中的程序就被称为进程。 现在我…

怎么加密文件夹才更安全?安全文件夹加密软件推荐

文件夹加密可以让其中数据更加安全&#xff0c;但并非所有加密方式都能够提高极高的安全强度。那么&#xff0c;怎么加密文件夹才更安全呢&#xff1f;下面我们就来了解一下那些安全的文件夹加密软件。 文件夹加密超级大师 如果要评选最安全的文件夹加密软件&#xff0c;那么文…

python GUI nicegui初识一(登录界面创建)

最近尝试了python的nicegui库&#xff0c;虽然可能也有一些不足&#xff0c;但个人感觉对于想要开发不过对ui设计感到很麻烦的人来说是很友好的了&#xff0c;毕竟nicegui可以利用TailwindCSS和Quasar进行ui开发&#xff0c;并且也支持定制自己的css样式。 这里记录一下自己利…

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构 2.自己对 TokenStore 的 redis实现 package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis…

leetcode刷题:1657. 确定两个字符串是否接近、1004. 最大连续1的个数 III

leetcode刷题:1657. 确定两个字符串是否接近、1004. 最大连续1的个数 III 1. 前言2. 1657. 确定两个字符串是否接近3. 1004. 最大连续1的个数 III4. 总结 1. 前言 上述两个题目位于leetcode75中&#xff0c;难度为中等&#xff0c;虽然对于大佬而言&#xff0c;可能很简单&…

2023年C++面试宝典

目录 第一章&#xff1a;C基础知识1.1 C语言起源与发展1.2 C的重要特点和优点1.3 C的数据类型和变量1.4 函数和命名空间1.5 运算符和表达式 第二章&#xff1a;面向对象编程2.1 类与对象的概念2.2 封装、继承和多态2.3 构造函数和析构函数2.4 静态成员和常量成员2.5 虚函数和纯…

maven install命令:将包安装在本地仓库,供本地的其它工程或者模块依赖

说明 有时候&#xff0c;自己本地的maven工程依赖于本地的其它工程&#xff0c;或者manven工程中的一个模块依赖于另外的模块&#xff0c;可以执行maven的install命令&#xff0c;将被依赖的包安装在maven本地仓库。 示例 一个工程包含几个模块&#xff0c;模块之间存在依赖…

【笔记】第94期-冯永吉-《湖仓集一体关键技术解读》-大数据百家讲坛-厦大数据库实验室主办20221022

https://www.bilibili.com/video/BV1714y1j7AU/?spm_id_from333.337.search-card.all.click&vd_sourcefa36a95b3c3fa4f32dd400f8cabddeaf

VSCode配置SSH远程免密登录服务器

VScode远程开发时&#xff0c;每次都需要输入密码&#xff0c;其实同理可以和其他应用类似配置免密登录&#xff0c;流程也类似。 1.在本地主机生成公钥和秘钥 ssh-keygen 2.将公钥内容添加至服务器 将生成钥对时会给出其保存路径&#xff0c;找到公钥&#xff0c;复制内容&am…

废弃的 电信光猫 改为 免费的wifi

修改为桥接模式即可。 1.修改电脑IP地址与光猫同一网段&#xff0c;例如192.168.1.2 掩码255.255.255.0。 电信光猫默认地址为 192.168.1.1 掩码为 255.255.255.0 2.网线或者无线连接光猫&#xff0c;无线wifi 名称&#xff08;SSID&#xff09;和密码 光猫背后都有。 3.浏…