保留关键字用于Python中的protobuf

时间:2015-05-09 17:05:36

标签: python protocol-buffers

一般来说,我有一个protobuf定义,它使用了Python关键字"来自"。它适用于Java / C#/ C ++,但是当涉及到Python时,我无法为其赋值。

以下是我的问题的详细信息。

我有一个如下所示的protobuf定义:

message Foo
{
    required int64 from = 10
    ...
}

由于"来自"是Python中的关键字,在生成python代码后,我无法编译如下代码:

foo = Foo()
foo.from = 1234

然后,我尝试使用setattr()来设置属性:

setattr(foo, 'from', 1234)

这给了我一个Protobuf例外:

AttributeError: Assignment not allowed to composite field "from" in protocol message object.

此时我无法更改定义,因为它已在系统中广泛使用。如果我可以解决使用"来自"任何帮助将不胜感激。 Python中的属性。

以下是ProtoBuf生成的代码:

import sys


_FOO = _descriptor.Descriptor(
  name='Foo',
  full_name='com.kerneljoy.Foo',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  fields=[
    _descriptor.FieldDescriptor(
      name='from', full_name='com.kerneljoy.Foo.from', index=0,
      number=10, type=3, cpp_type=2, label=2,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      options=None),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  options=None,
  is_extendable=False,
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=28,
  serialized_end=47,
)

DESCRIPTOR.message_types_by_name['Foo'] = _FOO

Foo = _reflection.GeneratedProtocolMessageType('Foo', (_message.Message,), dict(
  DESCRIPTOR = _FOO,
  __module__ = 'Foo_pb2'
  # @@protoc_insertion_point(class_scope:com.kerneljoy.Foo)
  ))
_sym_db.RegisterMessage(Foo)

3 个答案:

答案 0 :(得分:4)

经过几次尝试,我发现setattr()和getattr()可以解决这个问题。因为在我的生产代码中,来自'来自'指的是另一个protobuff定义。所以这里的解决方案如下:

foo = Foo()
object = getattr(foo, 'from')
object.bar = 'value'
object.bar2 = 'value2'

答案 1 :(得分:0)

很难实现" HasField"但是没有配对" GetField"。请考虑另一种实现:

def msg_GetField(msg, name, default_value=None, raise_on_not_exist=True):
    result = default_value
    #
    exist = False
    items = msg.ListFields()
    for desc, value in items:
        if name == desc.name:
            result = value
            exist = True
    #
    if raise_on_not_exist:
        if not exist:
            raise ValueError('No property')
    #
    return result

如果您知道如何操作,可以将其用作实用方法或make mixin。

答案 2 :(得分:0)

如果"来自"是一个原始变量(不是复合变量)。 set属性将起作用(您可以在错误消息中看到:" AttributeError:Assignment不允许复合字段") - 但是如果Foo包含在其他对象中,您将需要使用" MergeFrom"插入Foo以将其插入到包含对象中。

示例:

pb:

message Foo
{
   required int64 from = 1
} 
message Bar
{
  required Foo foo = 1
}

以下代码应该有效:

foo=Foo()
bar=Bar()
setattr(foo, 'from', 1204)
bar.MergeFrom(foo)