python – 序列化时Protobuf默认与“缺少必填字段”
发布时间:2020-12-20 11:42:05 所属栏目:Python 来源:网络整理
导读:包含必需字段的ProtoBuf消息上的SerializeToString()方法(具有默认值)始终抛出EncodeError,指出消息缺少那些必需字段.但是,如果我检查字段的值,则会设置所有默认值.例如: // mymessage.protomessage MyMessage { required int32 val = 1 [default=18];} 然
包含必需字段的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 很清楚,尽管在初始化时有一个默认值,但它只需要触摸每个字段.对我来说,默认的一个主要观点是只需要有人来更新非默认字段(或者他们需要更改的那些字段),所以这个set-it-to-own方法是一个非常令人遗憾的解决方案. 将字段标记为可选字段不是解决方案,因为根据我们的规范,这些字段是合法需要的. 更新:我尝试合作包括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,ActuallyInit以递归方式将每个字段设置为自身.这看起来像是一个丑陋的黑客,所以我将问题留在下面. 问题:有没有办法创建ProtoBuf消息实例并“说服”它每个已经初始化为默认的字段实际上不是错误? 解决方法
这是按预期工作的. required表示“作者必须明确填写此字段,而不是使用默认值”.如果您想要一个允许编写者使用其默认值离开该字段的字段,那么您需要可选项.这实际上是必需和可选之间的唯一区别,因此没有理由使用默认值.可以说,如果使用默认值定义了必需字段,Protobuf编译器应该引发错误,但我当时并不认为实现该限制.
(FWIW,长期以来被认为是a misfeature并且已经在Protobuf v3中删除了.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |