如何列出您在谷歌协议缓冲区中定义的属性?

时间:2014-11-04 17:32:20

标签: python protocol-buffers argparse introspection

我有一个google协议缓冲区定义,类似于followwing:

message Foo {
   required string Name = 1;
   optional string Address = 2;
   optional string NickName = 3;
   optional  int32  height = 4;
}

现在在python中,我想列出上面的所有属性,但只列出那些属性。但是,交互式python,我看到谷歌定义了更多的字段。所以这似乎有问题。

我已经查看了内省的一些stackoverflow帖子。有一个看起来不错的检查模块,但问题是谷歌协议缓冲区为我定义的其他成员。

有办法吗?

这就是我想做的事情。我有一个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这样的一些有希望的领域,但那是空的。

以下是答案:(由Kenton Varda回复)

import hello_pb2
h = hello_pb2.Foo()
f = hello_pb2.Foo()
f.DESCRIPTOR.fields_by_name.keys()

3 个答案:

答案 0 :(得分:6)

您希望迭代Foo.DESCRIPTOR.fields。请参阅Descriptor类:

https://developers.google.com/protocol-buffers/docs/reference/python/google.protobuf.descriptor.Descriptor-class

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

答案 1 :(得分:0)

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

//'pixels' is the blank image data object, automatically set to black
  //'.data' is an array holding the colour information as a Uint8Array
  for (let i = 0; i < pixels.data.length; i += 4) {
    //arr is the array from the our imageData argument (the raw personMask data)
    //so we set the image data object we have created, equal to the array from our image

    //this is turning our image data to the colour blue
    pixels.data[i] = arr[i+0]; //0 red value
    pixels.data[i + 1] = arr[i + 0]; //0 green value
    pixels.data[i + 2] = arr[i + 255]; //255 blue value
    pixels.data[i + 3] = arr[i + 255]; //255 alpha value

        let r = pixels.data[i]; //red
        let g = pixels.data[i + 1]; //greed
        let b = pixels.data[i + 2]; //blue
        let a = pixels.data[i + 3]; //blue

        if (r < 255) { //if any of these values are below 255
          r += fade; //increase them by 50 until they are 255
        }
        if (g < 255) {
          g += fade;
        }
        if (b < 255) {
          b += fade;
        }
        if (a < 255) {
          a += fade;
        }

        pixels.data[i] = r;
        pixels.data[i + 1] = g;
        pixels.data[i + 2] = b;
        pixels.data[i + 3] = a;
  }
  //The putImageData() method puts the image data from 'imgData' back onto the canvas.
  context.putImageData(pixels, 0, 0);

  return context.canvas;
}

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

答案 2 :(得分:0)

在 proto3 上,我无法让 @Kenton Varda 回答。

这对我有用:

from hello_pb2 import Foo

Foo.DESCRIPTOR.values_by_name