如何获取协议缓冲区中的所有字段名?
我想把一个proto里的所有字段名都放到一个列表里。有没有什么办法可以做到这一点?我查了文档,似乎没有相关的内容。
4 个回答
1
我在使用Python 3.9的时候遇到了一些问题,之前的一些解决方案不再有效了。所以我找到了一种新的方法,这个方法是通过消息对象的公共接口来实现的,而不是使用DESCRIPTOR
属性。
fields = [desc.name for desc, val in message.ListFields()]
不过要注意,这个方法只会获取那些已经设置过的字段。
1
你可以很简单地获取一个字段列表,方法如下:
message_fields = [field for field in message.DESCRIPTOR.fields_by_name]
14
这个回答对我没用。我调用 message.DESCRIPTOR.fields.keys()
的时候,出现了 AttributeError: 'list' object has no attribute 'keys'
的错误。
我不太明白为什么会这样。可能和消息是怎么定义或编译的有关。
我的解决办法是把每个字段对象放到一个列表里,然后获取每个字段的 name
属性。这样我就得到了一个包含所有字段名称的字符串列表。
res = [f.name for f in message.DESCRIPTOR.fields]
需要注意的是,这样做并不能递归地获取这些字段内部的字段名称。
55
每个proto类都有一个叫做 DESCRIPTOR类变量,这个变量可以用来查看对应protobuf消息的字段。
想了解更多,可以看看 Descriptor 和 FieldDescriptor 这两个类的文档。
下面是一个简单的例子,展示如何把 message
中所有字段的 FieldDescriptor
放到一个列表里:
res = message.DESCRIPTOR.fields
如果你想获取字段的名字,"正好和它们在.proto文件中出现的一样":
res = [field.name for field in message.DESCRIPTOR.fields]
或者(来自评论):
res = message.DESCRIPTOR.fields_by_name.keys()
如果你想获取字段的全名,"包括它们所在的范围":
res = [field.full_name for field in message.DESCRIPTOR.fields]