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 原理