python-3.x 使用protobuf时,我会得到attr-defined和name-defined错误

ars1skjm  于 2023-03-24  发布在  Python
关注(0)|答案(1)|浏览(137)

我在代码中使用protobuf,并使用命令生成了一个py文件:protoc --python_out=. samples/msg.proto,我的proto文件是:

syntax = "proto3";

message MsgPackage
{
  message Msg
  {
    uint32 code = 1;
    string msg = 2;
  }

  repeated Msg messages = 1;
}

| Package |版本|
| - ------|- ------|
| 巨蟒|三、十一、二|
| 梅皮|1.0.1节|
| 原buf|4.22.0|

Python protocol buffer编译器不直接生成数据访问代码,而是创建类型dynamic。所以通过mypy执行类型检查会得到一些错误:

如何解决错误,如:Name "MsgPackage.Msg" is not defined
谢谢!

gjmwrych

gjmwrych1#

当复制和粘贴文本很简单的时候,请不要使用图片。文本比图片好,因为(a)它可以让别人重复使用你的代码;(B)很可能比图像更持久。
要回答您的问题,原因是您没有正确使用重复字段。
下面是一个使用重复字段来创建和输出MsgPackage的解决方案:

from google.protobuf.internal.containers import RepeatedCompositeFieldContainer

from msg_pb2 import MsgPackage

# See print(type(m.messages) below
def show_msg(msgs: RepeatedCompositeFieldContainer[MsgPackage.Msg]) -> None:
    print(msgs)

# With Python, once you create the root Message, child messages
# e.g. `MsgPackage.Msg` are constructed automatically
m = MsgPackage()

# In this case, because `messages` is a repeated field of type `Msg`
# One (!) solution is to use `add` to add items
# Another solution is to use `extend`
x = m.messages.add()
x.code = 5
x.msg = "Hello"

print(m)

print(len(m.messages))

# It's common to iterate over repeated fields
for i in m.messages:
    print(f"{i.code}: {i.msg}")

# RepeatedCompositeFieldContainer
print(type(m.messages))

show_msg(m.messages)

有关如何使用Python重复字段的说明,请参见Protobuf文档。
下面是google.protobuf.internal.containers的API文档

注意您也可以使用protoc生成PYI文件。编辑器经常使用这些文件对protoc生成的Python代码进行类型检查:

protoc --python_out=${PWD} --pyi_out=${PWD} msg.proto

相关问题