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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫异常处理心得:应对网络故障和资源消耗

作为一名专业的爬虫代理,我知道在爬取数据的过程中,遇到网络故障和资源消耗问题是再正常不过了。今天,我将与大家分享一些关于如何处理这些异常情况的心得和技巧。不论你是在处理网络不稳定还是资源消耗过大的问题,这些技巧能够帮…

聊聊 Docker 和 Dockerfile

目录 一、前言 二、了解Dockerfile 三、Dockerfile 指令 四、多阶段构建 五、Dockerfile 高级用法 六、小结 一、前言 对于开发人员来说,会Docker而不知道Dockerfile等于不会Docker,上一篇文章带大家学习了Docker的基本使用方法:《一文…

vue 老项目 npm install 报错Python,c++等相关错误

​​​ 老项目npm install 下载依赖包报错 解决方法: //下载python 1、 npm install --global --production windows-build-tools//配置环境 : 也可暂时不用配置,能用就不用配置(npm config set python "D:\Python27\python.exe&q…

一键开启ChatGPT“危险发言”

‍ ‍ 大数据文摘授权转载自学术头条 作者:Hazel Yan 编辑:佩奇 随着大模型技术的普及,AI 聊天机器人已成为社交娱乐、客户服务和教育辅助的常见工具之一。 然而,不安全的 AI 聊天机器人可能会被部分人用于传播虚假信息、操纵舆…

8.7工作总结

一、我们想自定义一个titileBar出现如下这种情况,发现他原来的titileBar还未隐藏。 后来我尝试修改主题使得他没有主题noActionBar发现也不行,后来我参考原先我看过的项目使用了如下代码 this.getActionBar().hide();发现会报这个错误java.lang.NullPoi…

HTTPS-RSA握手

RSA握手过程 HTTPS采用了公钥加密和对称加密结合的方式进行数据加密和解密 RSA握手是HTTPS连接建立过程中的一个关键步骤,用于确保通信双方的身份验证和生成对称加密所需的密钥 通过RSA握手过程,客户端和服务器可以协商出一个共享的对称密钥,…

使用pg_prewarm缓存PostgreSQL数据库表

pg_prewarm pg_prewarm 直接利用系统缓存的代码,对操作系统发出异步prefetch请求,在应用中,尤其在OLAP的情况下,对于大表的分析等等是非常耗费查询的时间的,而即使我们使用select table的方式,这张表也并不可能将所有…

SpringCloud实用篇1——eureka注册中心 Ribbon负载均衡原理 nacos注册中心

目录 1 微服务1.1 微服务的演变1.2 微服务1.3 SpringCloud1.4 小结 2 服务拆分及远程调用2.1 服务拆分2.2 服务拆分案例2.3 实现远程调用2.4 提供者与消费者 3 Eureka注册中心3.1 Eureka的结构和作用3.2 搭建eureka-server3.3 服务注册3.4 服务发现 4 Ribbon负载均衡4.1 负载均…

rust基础

这是笔者学习rust的学习笔记(如有谬误,请君轻喷) 参考视频: https://www.bilibili.com/video/BV1hp4y1k7SV参考书籍:rust程序设计语言:https://rust.bootcss.com/title-page.htmlmarkdown地址:h…

【雕爷学编程】Arduino动手做(192)---Air724UG Cat1 物联网4G模块2

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

坐标转换-使用geotools读取和转换地理空间表的坐标系(sqlserver、postgresql)

前言: 业务上通过GIS软件将空间数据导入到数据库时,因为不同的数据来源和软件设置,可能导入到数据库的空间表坐标系是各种各样的。 如果要把数据库空间表发布到geoserver并且统一坐标系,只是在geoserver单纯的设置坐标系只是改了…

[PyTorch][chapter 46][LSTM -1]

前言: 长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的。 目录: 背景简介 LSTM C…

【windows】windows上如何使用linux命令?

前言 windows上的bat命令感觉不方便,想在windows上使用linux命令。 有人提供了轮子,本文简单介绍一些该轮子的安装与使用,希望能够帮助到和我有一起需求的网友。 我的答案是busybox。 1.安装busybox.exe 在这个网站上安装busybox busyb…

Windows下安装Kafka(图文记录详细步骤)

Windows下安装Kafka Kafka简介一、Kafka安装前提安装Kafka之前,需要安装JDK、Zookeeper、Scala。1.1、JDK安装(version:1.8)1.1.1、JDK官网下载1.1.2、JDK网盘下载1.1.3、JDK安装 1.2、Zookeeper安装1.2.1、Zookeeper官网下载1.2.…

FPGA纯verilog实现 LZMA 数据压缩,提供工程源码和技术支持

目录 1、前言2、我这儿已有的FPGA压缩算法方案3、FPGA LZMA数据压缩功能和性能4、FPGA LZMA 数据压缩设计方案输入输出接口描述数据处理流程LZ检索器数据同步LZMA 压缩器 为输出LZMA压缩流添加文件头 5、vivado仿真6、福利:工程代码的获取 1、前言 说到FPGA的应用&…

计算机二级Python基本操作题-序号45

1. 键盘输入一组水果名称并以空格分隔,共一行。 示例格式如下: 苹果 芒果 草莓 芒果 苹果 草莓 芒果 香蕉 芒果 草莓 统计各类型的数量,从数量多到少的顺序输出类型及对应数量,以英文冒号分隔,每个类型行。输出结果保存…

学生管理系统(升级版)

import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class Demo_学生管理系统 {public static void main(String[] args) {ArrayList<User> list new ArrayList<>();Scanner sc new Scanner(System.in);while (true) {Syste…

Hive创建外部表详细步骤

① 在hive中执行HDFS命令&#xff1a;创建/data目录 hive命令终端输入&#xff1a; hive> dfs -mkdir -p /data; 或者在linux命令终端输入&#xff1a; hdfs dfs -mkdir -p /data; ② 在hive中执行HDFS命令&#xff1a;上传/emp.txt至HDFS的data目录下&#xff0c;并命名为…

励志长篇小说《周兴和》书连载之八 处心积虑揽工程

处心积虑揽工程 如何去揽工程&#xff0c;周兴和其实早就谋划好了。 那一天&#xff0c;周兴和与爱人王琼华的姐夫严忠伦、大舅子王安全提了10来只大公鸡&#xff0c;背着两只狗腿&#xff0c;以及城里人喜欢的干豇豆等山区土特产&#xff0c;坐车来到省城成都。下了车&#x…

zookeeper --- 基础篇

一、zookeeper简介 1.1、什么是zookeeper zookeeper官网&#xff1a;https://zookeeper.apache.org/ 大数据生态系统里的很多组件的命名都是某种动物或者昆虫&#xff0c;他是用来管 Hadoop&#xff08;大象&#xff09;、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理…