CyberRT_protobuf_原理介绍_实现以及使用

python 反射

可以获取对象的类型、属性、方法等信息,实现对对象结构的动态探索和操作。
 内置函数和特殊方法:Python提供了一系列内置函数和特殊方法,
 如type()、dir()、getattr()、setattr()、hasattr()等,这些函数和方法为反射提供了基础工具。
     hasattr(object,'attrName'):判断该对象是否有指定名字的属性或方法,返回值是bool类型
	 getattr(object,'attrName'):获取对象指定名称的属性或方法,返回值是str类型
模块支持:Python的inspect模块提供了更加强大的反射功能
python  Python支持动态导入模块,即在运行时根据变量或条件来导入模块 importlib是Python提供的一个内置模块

protobuf 原理

 Protobuf的原理,包括其数据结构、编码规则以及使用方式
   Protobuf不是一种RPC协议,因为它不涉及通信,而只是一种数据序列化协议
  序列化 包括对数据进行编码 + 存储  
    存储方式-
         : 采用 TLV存储方式,即TAG-Length-Value(标识-长度-字段值) Tag-Length-Value方式
            其中 Length可选存储,如 储存Varint编码数据就不需要存储Length
               即 TV存储方式
	编码方式--存储方式--占用字节
	    Varint 编码
        ZigZag 编码:有符号整数映射到无符号整数,然后再使用 Varints 编码		  
	Protocol Buffer对于不同数据类型 采用不同的 序列化方式(编码方式 & 数据存储方式)			
protobuf协议原理及实现

protobuf

protobuf --反射
   使用反射动态地创建类型的实例,将类型绑定到现有对象,
    或从现有对象中获取类型。
   然后,可以调用类型的方法或访问其字段和属性
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf.internal import enum_type_wrapper

from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
          protobuf.internal import enum_type_wrapper
          protobuf.internal import python_message
          protobuf import message as _message
          protobuf import reflection as _reflection

google.protobuf.descriptor_pool

protobuf 反射实现解析.
    C++中,我们不得不借助于ProtoBuf的反射机制
     Message的Descriptor和Reflection
	    通过Descriptor,我们可以获得一个字段的FieldDescriptor
		Reflection就是具体执行相关反射操作,比如当拿到了Message的FieldDescriptor,
		   就可以通过Reflection来读写这个字段
      一个 protobuf 的 message 的 reflection API 是通过  descriptor 建立起来的
	  protobuf通过proto文件生成相应的message和service,
	  protobuf也通过proto文件提供反射机制,
	    程序在运行时可以通过proto获取任意message和任意service的属性和方法,
	    也可以在运行时调用message的属性和方法。
#### 基本概念
Descriptor系列.::google::protobuf::Descriptor 系列包括:
Descriptor 系列最大的message是 FileDescriptor . 
    每个文件会生成一个包含本文件所有信息的FileDescriptor包
 Descriptor – 用来描述 消息
 FieldDescriptor – 用来描述 字段
 OneofDescriptor – 用来描述 联合体
 EnumDescriptor – 用来描述 枚举
 EnumValueDescriptor – 用来描述 枚举值
 ServiceDescriptor – 用来描述 服务器
 MethodDescriptor – 用来描述 服务器方法
 FileDescriptor – 用来描述 文件
这些 Descriptor系列的数据则是由 DescriptorProto系列的数据 , 利用DescriptorBuilder工具类来填充的 . 

使用PB 反射

protobuf已经解析好proto文件,并将所有的Descriptor放在DescriptorPool中了。
 可以根据proto的文件名,通过DescriptorPool获取到相应的FileDescriptor
 
descriptor_pool来获取.proto文件中定义的消息类型、枚举类型、服务等的描述符。
  这样我们可以在不实例化消息对象的情况下获取到它们的信息 
  
 看出执行构造函数的时候会触发 Descriptor 表的构 

1. 通过Message获取单个字段的FieldDescriptor
2. 通过Message获取其Reflection
3. 通过Reflection来操作FieldDescriptor,从而动态获取或修改单个字段 

介绍

google.protobuf.symbol_database¶
    A database of Python protocol buffer generated symbols.	
	_sym_db = _symbol_database.Default()
	_sym_db.RegisterMessage(Person)
 default SymbolDatabase	

参考

https://googleapis.dev/python/protobuf/latest/google/protobuf/descriptor_pool.html
精通 protobuf 原理
posted @ 2024-05-05 20:59  辰令  阅读(29)  评论(0编辑  收藏  举报