V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
vegetableChick
V2EX  ›  Python

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

  •  
  •   vegetableChick · 2023-08-25 18:16:22 +08:00 · 1231 次点击
    这是一个创建于 480 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在 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协议,所以不太懂原理,求教大家, 谢谢

    4 条回复    2023-08-25 21:54:34 +08:00
    so1n
        1
    so1n  
       2023-08-25 18:22:17 +08:00
    Protobuf 生成的代码类型并不是 Python 的类型,它们只是长得像 Python 对应的类型而已,比如 map, reapeated 之类的,如果你在 pymysql 中使用,要显式的把他们转为 list, dict
    flyqie
        2
    flyqie  
       2023-08-25 18:22:59 +08:00
    syntax = "proto3";

    common_pb2.py

    。。。。?
    e3c78a97e0f8
        3
    e3c78a97e0f8  
       2023-08-25 19:17:29 +08:00 via iPhone
    ClientTypeEnum = _reflection.GeneratedProtocolMessageType('ClientTypeEnum', (_message.Message,), {
    'DESCRIPTOR' : _CLIENTTYPEENUM,
    '__module__' : 'api.pay_center.common.common_pb2'
    # @@protoc_insertion_point(class_scope:common.ClientTypeEnum)
    })

    这不是有吗
    flyqie
        4
    flyqie  
       2023-08-25 21:54:34 +08:00
    @flyqie #2

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

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

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

    好像方法还挺多,你试试?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5772 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 01:49 · PVG 09:49 · LAX 17:49 · JFK 20:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.