You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Protobuf json_format将Python字典中的int转为float?

解决Protobuf Struct转换时整数自动转浮点数的问题

问题原因

Protobuf的struct_pb2.Struct是为兼容JSON数据结构设计的,而JSON的Number类型不区分整数和浮点数——Struct里所有数字都会被统一存储为double类型(对应Protobuf Value的number_value字段),所以不管你传入的是整数还是浮点数,最终都会以浮点数形式呈现。

解决方案

1. 自定义Protobuf消息类型(推荐)

如果需要严格区分整数和浮点数,不要用默认的Struct,而是自己定义匹配业务结构的Protobuf消息,明确指定字段类型。

比如针对你的输入层配置,编写.proto文件:

syntax = "proto3";

message LayerConfig {
  string class_name = 1;
  message ConfigDetail {
    // 用optional字段处理原字典中的None,proto3支持可选字段
    optional int32 batch_input_dim_1 = 1;
    int32 batch_input_dim_2 = 2; // 明确指定为整数类型
    string dtype = 3;
    bool sparse = 4;
    bool ragged = 5;
    string name = 6;
  }
  ConfigDetail config = 2;
}

将.proto编译为Python代码后,用这个自定义消息类型解析数据,就能精准保留整数类型。原字典中的None可通过optional字段表示,后续使用时再转换回None即可。

2. 转换后手动修正类型(临时 workaround)

如果必须使用Struct,只能在转换完成后手动遍历结构,把需要的浮点数转回整数:

import json
from google.protobuf import struct_pb2

layer_config = {
    'class_name': 'InputLayer',
    'config': {
        'batch_input_shape': (None, 32),
        'dtype': 'float32',
        'sparse': False,
        'ragged': False,
        'name': 'input_5'
    }
}

# 转换为Struct
s = struct_pb2.Struct()
s.update(layer_config)

# 定义工具函数,读取值时自动修正整数类型
def get_typed_value(val):
    if val.HasField('number_value'):
        num = val.number_value
        return int(num) if num.is_integer() else num
    elif val.HasField('null_value'):
        return None
    return val.string_value if val.HasField('string_value') else val.bool_value

# 读取并修正batch_input_shape的值
corrected_shape = [get_typed_value(v) for v in s['config']['batch_input_shape'].list_value.values]
print(corrected_shape)  # 输出 [None, 32]

这种方式只能在读取数据时做类型修正,Struct内部存储的还是浮点数,适合无法修改消息类型的场景。

内容的提问来源于stack exchange,提问作者techytushar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:50:27