Python 如何列出在google协议缓冲区中定义的属性?

Python 如何列出在google协议缓冲区中定义的属性?,python,protocol-buffers,argparse,introspection,Python,Protocol Buffers,Argparse,Introspection,我有一个google协议缓冲区定义,它类似于以下内容: message Foo { required string Name = 1; optional string Address = 2; optional string NickName = 3; optional int32 height = 4; } 现在在python中,我想列出上面的所有属性,但只列出那些属性。然而,在交互式python中,我看到google定义了更多的字段。所以这似乎有问题 我看过一些

我有一个google协议缓冲区定义,它类似于以下内容:

message Foo {
   required string Name = 1;
   optional string Address = 2;
   optional string NickName = 3;
   optional  int32  height = 4;
}
现在在python中,我想列出上面的所有属性,但只列出那些属性。然而,在交互式python中,我看到google定义了更多的字段。所以这似乎有问题

我看过一些关于内省的帖子。有一个inspect模块看起来不错,但问题是google protocol buffers为我定义的其他成员

有没有办法做到这一点

这是我想做的。我有一个python实用程序,它从命令行中填写上述字段。我使用argparse,我将:

parser = argparse.ArgumentParser(...)
parser.add_argument( "--attribute_name", blah)
我想将add_argument()放在一个循环中,并基于proto文件定义使其成为动态的。基本上,我不想每次更改proto文件时都不断修改实用程序的代码。看起来我应该能够用python完成这项工作。我只是不知道怎么做

有人有什么建议吗

谢谢

为了获得更多信息,我采用了上面的示例,并使用protoc对其进行了编译。以下是交互式输出:

>>> import hello_pb2
>>> h = hello_pb2.Foo()
>>> dir(h)
['ADDRESS_FIELD_NUMBER', 'Address', 'ByteSize', 'Clear', 'ClearExtension', 'ClearField', 'CopyFrom', 'DESCRIPTOR', 'FindInitializationErrors', 'FromString', 'HEIGHT_FIELD_NUMBER', 'HasExtension', 'HasField', 'IsInitialized', 'ListFields', 'MergeFrom', 'MergeFromString', 'NAME_FIELD_NUMBER', 'NICKNAME_FIELD_NUMBER', 'Name', 'NickName', 'ParseFromString', 'RegisterExtension', 'SerializePartialToString', 'SerializeToString', 'SetInParent', '_InternalParse', '_InternalSerialize', '_Modified', '_SetListener', '__class__', '__deepcopy__', '__delattr__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_cached_byte_size', '_cached_byte_size_dirty', '_decoders_by_tag', '_extensions_by_name', '_extensions_by_number', '_fields', '_is_present_in_parent', '_listener', '_listener_for_children', 'height']
我输入了一些有希望的字段,如_fields,但那是空的

答案如下:(由肯顿·瓦尔达回复)


您希望迭代
Foo.DESCRIPTOR.fields
。请参见
描述符
类:


每个消息类都有一个静态成员
描述符
,它是该类型的描述符。

如果要将protobuf对象转换为字典:

import hello_pb2

def proto2dict(msg):
    hsh_val = dict(msg.ListFields())
    d = dict((k, hsh_val[hsh]) for k, hsh in msg.DESCRIPTOR.fields_by_name.items())
    return d

data = {"Name":"name", "Address":"address", "NickName":"nick", "height": 6}
msg = hello_pb2.Foo(**data)

assert proto2dict(msg) == data

注意:看起来效率低下,可能不适用于嵌套定义。

在proto3上,我无法使@Kenton Varda answer工作

这是我的工作:

from hello_pb2 import Foo

Foo.DESCRIPTOR.values_by_name

您可以删除所有以“_”开头的属性以及所有函数。这些都将由类定义,而不是由参数定义。这可能会留下用户定义的字段,再加上一些标准。标准在不同的用户定义中是相同的。谢谢你的建议。这也是一个很好的方法,但我只想要我定义的字段。这是一个很好的备份计划。你的原语版本是什么?是的,你是对的。谢谢你是怎么发现它这么快的?我写了谷歌的大部分开源protobuf代码。:)谢谢你的技术。我们公司现在正在广泛使用它。我可以通过
dir()
protobuf 2.x消息直接查看所有属性。这是protobuf 3.x的问题吗?我在python3中对@nn0p有同样的问题,我看不到任何带有
dir()
的字段,不知道如何使
dir()
工作。
from hello_pb2 import Foo

Foo.DESCRIPTOR.values_by_name