ProtoBuf消息的SerializeToString()方法包含有默认值的必需字段,它总是抛出EncodeError
,说明消息缺少这些必需字段。但是,如果我检查字段的值,则设置所有默认值。例如:
// mymessage.proto
message MyMessage {
required int32 val = 1 [default=18];
}
然后在python中:
^{pr2}$另一方面,如果我这样做:
m.val = m.val
print m.SerializeToString() # No Error
很明显,它只需要触摸每个字段,尽管初始化时有一个默认值。对我来说,拥有默认值的一个主要点是只需要有人更新非默认字段(或那些需要更改的字段),所以这个setittoself方法是一个非常糟糕的解决方案。在
将字段标记为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
,后者递归地将每个字段设置为自己。这似乎是一个丑陋的黑客攻击,所以我留下下面的问题。在
问题:有没有办法创建ProtoBuf消息实例并“说服”它,每个已经初始化为默认字段的字段实际上都不是错误?在
这是按计划工作的。
required
表示“编写器必须显式填写此字段,而不是使用默认值”。如果您想要一个允许编写器保留其默认值的字段,那么您需要optional
。这实际上是required
和optional
之间的唯一区别,所以根本没有理由将required
与默认值一起使用。可以说,如果一个required
字段是用默认值定义的,Protobuf编译器应该会引发一个错误,但是我当时没有考虑实现这个限制。在(FWIW,
required
长期以来被认为是{a1},并在protobufv3中被删除了。)相关问题 更多 >
编程相关推荐