Python proto3 enum 编译后得不到对应的枚举值类吗, 如果可以的话如何得到?

257 天前
 vegetableChick

我在 common.proto 中定义了两个枚举类型

syntax = "proto3";

package common;

message ClientTypeEnum {
  enum ClientType {
    SM = 0;
    VL = 1;
  }
};

enum ErrCode{
  PayCenterErrorCode_SUCCESS                      = 0;
  PayCenterErrorCode_REQ_PARAMS_ERROR             = 1000000;
  PayCenterErrorCode__ERROR                       = 1000001;
  PayCenterErrorCode__UNKNOWN_ERROR               = 1000002;
  PayCenterErrorCode__ACCOUNT_NOT_EXIST           = 1000003;
}

用下面的编译命令进行编译后

	python -m grpc_tools.protoc --proto_path=. \
		--experimental_allow_proto3_optional \
		--error_format=gcc \
		--python_out=./py_interface/ --grpc_python_out=./py_interface/ common.proto

得到了 common_pb2.py

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: api/pay_center/common/common.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()




DESCRIPTOR = _descriptor.FileDescriptor(
  name='api/pay_center/common/common.proto',
  package='common',
  syntax='proto3',
  serialized_options=b'Z=git.domob-inc.cn/bluevision/bv_interface_go/pay_center/common',
  create_key=_descriptor._internal_create_key,
  serialized_pb=b'\n\"api/pay_center/common/common.proto\x12\x06\x63ommon\"j\n\x0e\x43lientTypeEnum\x12\x36\n\x0b\x63lient_type\x18\x01 \x01(\x0e\x32!.common.ClientTypeEnum.ClientType\" \n\nClientType\x12\x07\n\x03SMB\x10\x00\x12\t\n\x05\x42V_VL\x10\x01*\xcb\x01\n\x07\x45rrCode\x12\x1e\n\x1aPayCenterErrorCode_SUCCESS\x10\x00\x12)\n#PayCenterErrorCode_REQ_PARAMS_ERROR\x10\xc0\x84=\x12\x1f\n\x19PayCenterErrorCode__ERROR\x10\xc1\x84=\x12\'\n!PayCenterErrorCode__UNKNOWN_ERROR\x10\xc2\x84=\x12+\n%PayCenterErrorCode__ACCOUNT_NOT_EXIST\x10\xc3\x84=B?Z=git.domob-inc.cn/bluevision/bv_interface_go/pay_center/commonb\x06proto3'
)

_ERRCODE = _descriptor.EnumDescriptor(
  name='ErrCode',
  full_name='common.ErrCode',
  filename=None,
  file=DESCRIPTOR,
  create_key=_descriptor._internal_create_key,
  values=[
    _descriptor.EnumValueDescriptor(
      name='PayCenterErrorCode_SUCCESS', index=0, number=0,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
    _descriptor.EnumValueDescriptor(
      name='PayCenterErrorCode_REQ_PARAMS_ERROR', index=1, number=1000000,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
    _descriptor.EnumValueDescriptor(
      name='PayCenterErrorCode__ERROR', index=2, number=1000001,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
    _descriptor.EnumValueDescriptor(
      name='PayCenterErrorCode__UNKNOWN_ERROR', index=3, number=1000002,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
    _descriptor.EnumValueDescriptor(
      name='PayCenterErrorCode__ACCOUNT_NOT_EXIST', index=4, number=1000003,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
  ],
  containing_type=None,
  serialized_options=None,
  serialized_start=155,
  serialized_end=358,
)
_sym_db.RegisterEnumDescriptor(_ERRCODE)

ErrCode = enum_type_wrapper.EnumTypeWrapper(_ERRCODE)
PayCenterErrorCode_SUCCESS = 0
PayCenterErrorCode_REQ_PARAMS_ERROR = 1000000
PayCenterErrorCode__ERROR = 1000001
PayCenterErrorCode__UNKNOWN_ERROR = 1000002
PayCenterErrorCode__ACCOUNT_NOT_EXIST = 1000003


_CLIENTTYPEENUM_CLIENTTYPE = _descriptor.EnumDescriptor(
  name='ClientType',
  full_name='common.ClientTypeEnum.ClientType',
  filename=None,
  file=DESCRIPTOR,
  create_key=_descriptor._internal_create_key,
  values=[
    _descriptor.EnumValueDescriptor(
      name='SM', index=0, number=0,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
    _descriptor.EnumValueDescriptor(
      name='VL', index=1, number=1,
      serialized_options=None,
      type=None,
      create_key=_descriptor._internal_create_key),
  ],
  containing_type=None,
  serialized_options=None,
  serialized_start=120,
  serialized_end=152,
)
_sym_db.RegisterEnumDescriptor(_CLIENTTYPEENUM_CLIENTTYPE)


_CLIENTTYPEENUM = _descriptor.Descriptor(
  name='ClientTypeEnum',
  full_name='common.ClientTypeEnum',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  create_key=_descriptor._internal_create_key,
  fields=[
    _descriptor.FieldDescriptor(
      name='client_type', full_name='common.ClientTypeEnum.client_type', index=0,
      number=1, type=14, cpp_type=8, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
    _CLIENTTYPEENUM_CLIENTTYPE,
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=46,
  serialized_end=152,
)

_CLIENTTYPEENUM.fields_by_name['client_type'].enum_type = _CLIENTTYPEENUM_CLIENTTYPE
_CLIENTTYPEENUM_CLIENTTYPE.containing_type = _CLIENTTYPEENUM
DESCRIPTOR.message_types_by_name['ClientTypeEnum'] = _CLIENTTYPEENUM
DESCRIPTOR.enum_types_by_name['ErrCode'] = _ERRCODE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)

ClientTypeEnum = _reflection.GeneratedProtocolMessageType('ClientTypeEnum', (_message.Message,), {
  'DESCRIPTOR' : _CLIENTTYPEENUM,
  '__module__' : 'api.pay_center.common.common_pb2'
  # @@protoc_insertion_point(class_scope:common.ClientTypeEnum)
  })
_sym_db.RegisterMessage(ClientTypeEnum)


DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

为什么编译后没有生成对应的 Enum 类型, 如果可以的话 如何调整才能获取

class ClientTypeEnum(proto.Message):

    class ClientType(proto.Enum):
        SM = 0
        VL = 1

开发环境 Python 3.9.17 + ibprotoc 3.17.3 + mac 12.5.1

python -m grpc_tools.protoc  
libprotoc 3.17.3

刚开始用protobuffer协议,所以不太懂原理,求教大家, 谢谢

1032 次点击
所在节点    Python
4 条回复
so1n
257 天前
Protobuf 生成的代码类型并不是 Python 的类型,它们只是长得像 Python 对应的类型而已,比如 map, reapeated 之类的,如果你在 pymysql 中使用,要显式的把他们转为 list, dict
flyqie
257 天前
syntax = "proto3";

common_pb2.py

。。。。?
e3c78a97e0f8
257 天前
ClientTypeEnum = _reflection.GeneratedProtocolMessageType('ClientTypeEnum', (_message.Message,), {
'DESCRIPTOR' : _CLIENTTYPEENUM,
'__module__' : 'api.pay_center.common.common_pb2'
# @@protoc_insertion_point(class_scope:common.ClientTypeEnum)
})

这不是有吗
flyqie
257 天前
@flyqie #2

抽空看了下文档,是我见识短浅了。。

`Currently both proto2 and proto3 use _pb2.py for their generated files.`

关于 enum 官方文档: https://protobuf.dev/reference/python/python-generated/#enum

好像方法还挺多,你试试?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/968353

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX