【发布时间】:2015-04-09 16:55:55
【问题描述】:
包含具有默认值的必填字段的 ProtoBuf 消息上的 SerializeToString() 方法总是抛出 EncodeError ,说明该消息缺少那些必填字段。但是,如果我检查字段的值,则会设置所有默认值。例如:
// mymessage.proto
message MyMessage {
required int32 val = 1 [default=18];
}
然后在python中:
from mymessage_pb2.py import MyMessage
m = MyMessage()
print m.val # Shows m.val == 18
print m.SerializeToString() # EncodeError
另一方面,如果我这样做:
m.val = m.val
print m.SerializeToString() # No Error
很明显,尽管在初始化时具有默认值,但它只需要触及每个字段。对我来说,使用默认值的要点之一是只要求某人更新非默认字段(或他们需要更改的字段),因此这种自行设置的方法是一个非常抱歉的解决方案。
将字段标记为 optional 不是解决方案,因为根据我们的规范,这些字段是合法需要的。
更新:我尝试的变通方法包括 MergeFrom 和 CopyFrom,但均未奏效。所以我写了这个:
def ActuallyInit(obj):
err = []
obj.IsInitialized(err)
for field in err:
attr = obj.__getattribute__(field)
try:
obj.__setattr__(field, attr)
except:
ActuallyInit(attr)
然后创建他们的 protobuf 对象并将其传递给ActuallyInit,后者递归地将每个字段设置为自身。这似乎是一个丑陋的 hack,所以我将下面的问题留待解决。
问题:有没有办法创建 ProtoBuf 消息实例并“说服”它每个已经初始化为默认的字段实际上都不是错误?
【问题讨论】: