由于未解析的引用(Mac OS),无法在代码中导入protoc生成的Python类



我试图在项目中使用协议缓冲区,但问题是当我使用protoc生成python类时。生成的文件与谷歌提供的示例中的文件完全不同,并且无法在任何文件中导入,因为存在一些未解析的引用
因此,我遵循了本页中的示例:https://developers.google.com/protocol-buffers/docs/pythontutorial

先决条件

  1. M1 Mac上的macOS 12.6操作系统
  2. 我在用pyenvpyenv-virtualenv管理的虚拟环境中使用了Python 3.9.11
  3. 我从下载了最新的python包https://github.com/protocolbuffers/protobuf/releases/tag/v21.7
  4. 我用自制软件安装了protobufhttps://formulae.brew.sh/formula/protobuf
  5. 我按照此说明安装软件包https://github.com/protocolbuffers/protobuf/tree/v21.7/python
  6. 我还从上面的protobuff包中复制了c++协议,看看它是否有帮助,但没有

我最终得到的包裹是:

$ python --version
$ Python 3.9.11
$ 
$ protoc --version
$ libprotoc 3.21.7
$
$ pip freeze | grep protobuf
$ protobuf==3.20.2

代码

首先,我尝试从本教程.proto文件生成一个python类:

syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}

然后我使用该命令生成python类

protoc -I=. --python_out=. tutorial.proto

输出文件为:

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: tutorial.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()


DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'nx0etutorial.protox12x08tutorial"xd5x01nx06Personx12x0cnx04namex18x01 x01(tx12nnx02idx18x02 x01(x05x12rnx05x65mailx18x03 x01(tx12,nx06phonesx18x04 x03(x0bx32x1c.tutorial.Person.PhoneNumberx1aGnx0bPhoneNumberx12x0enx06numberx18x01 x01(tx12(nx04typex18x02 x01(x0ex32x1a.tutorial.Person.PhoneType"+ntPhoneTypex12nnx06MOBILEx10x00x12x08nx04HOMEx10x01x12x08nx04WORKx10x02"/nx0bx41x64x64ressBookx12 nx06peoplex18x01 x03(x0bx32x10.tutorial.Person')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tutorial_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_PERSON._serialized_start=29
_PERSON._serialized_end=242
_PERSON_PHONENUMBER._serialized_start=126
_PERSON_PHONENUMBER._serialized_end=197
_PERSON_PHONETYPE._serialized_start=199
_PERSON_PHONETYPE._serialized_end=242
_ADDRESSBOOK._serialized_start=244
_ADDRESSBOOK._serialized_end=291
# @@protoc_insertion_point(module_scope)

因此,正如您所看到的,没有创建元类,并且DESCRIPTOR.options=None行下面的所有常量都是未解析引用。

当我稍后尝试导入该文件时,运行时显然会崩溃,因为这不是一个有效的Python文件。

有什么想法吗?

事实证明,示例代码运行良好,问题出现在我的代码中的其他地方
让我对代码产生疑问的一些令人困惑的事情是:

  1. 官方页面上的例子已经过时了。谷歌已经改变了原buff的生成方式,不再有元类了
  2. 有动态导入,因此IDE将突出显示未定义的_PERSON等描述符,但代码在启动时仍然有效

所以我花了一些时间调试一个不存在的问题;(。

我也遇到了同样的问题。它在pb文件中报告了一堆错误,但在其他文件中可以正常引用。在我看来,可能只是协议更新导致编辑器无法识别这种新格式。

相关内容

  • 没有找到相关文章

最新更新