解码python中byte编码的object

本文介绍了在Python3环境中处理Python2字节编码的pickle对象的问题。当尝试读取在Python2.7环境下创建的infos.pkl文件时,遇到字节编码的键。通过分析错误,发现需要将字节编码的键转换为可访问的字符串。作者分享了解决此问题的转换函数,包括将字节编码的字典转换为普通字典以及将字节编码的对象转换为常规对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题起因

这个问题的起因是我需要在Python3.5环境下读取一个infos.pkl,但这个pkl是在python2.7环境下存储的
首先读取的时候要加encoding=’bytes’,其他编码均会报错ordinal not in range(128)

with open(opt.infos_path,'rb') as f:
    infos = cPickle.load(f, encoding='bytes')

这个infos读进来是一个dict,dict里每个key中装了1个对象
打印infos.keys(),输出
dict_keys([b’epoch’, b’iter’, b’opt’, b’split_ix’])
说明这个dict的key是由byte编码的

原代码如下

opt.input_fc_dir = infos['opt'].input_fc_dir

我改为

opt.input_fc_dir = infos[b'opt'].input_fc_dir

会报错
AttributeError: ‘Namespace’ object has no attribute ‘input_fc_dir’
因为infos[b’opt’]中的key也是Byte编码的,它在namespace中找不到input_fc_dir这个键。

opt.input_fc_dir = infos[b'opt'][b'input_fc_dir']

会报错TypeError: keys must be a string
直接 infos[b’opt’].decode()也会报错
TypeError: encoding without a string argument

解决过程

直接打印infos[b’opt’]输出
Namespace(b’att_feat_size’=2048, b’att_hid_size’=512, b’input_fc_dir’=b’data/cocotalk_fc’, b’input_json’=b’data/cocotalk.json’, b’input_label_h5’=b’data/cocotalk_label.h5’,)
我发现程序是知道opt里面有哪些键的,只是这些键名被byte编码了,正常的手段无法访问到它们。

那我把这个Object转换为dict不就好了?直接百度了一段转换代码,但转换过程中就会报错
因为对这个byte编码的object,使用dir(object)或是getattr(object,’input_json’)都不行,都会报错bytes无法转换为string。
既然这些法子都不行,不如干脆釜底抽薪,直接str(object),转成字符串,再把字符串转成正常的object好了。

转换函数

于是写了一个解码byte_object的转换函数

def dic2obj(d):  
    top = type('new', (object,), d)  
    seqs = tuple, list, set, frozenset  
    for i, j in d.items():  
        if isinstance(j, dict):  
            setattr(top, i, obj_dic(j))  
        elif isinstance(j, seqs):  
            setattr(top, i,   
                type(j)(obj_dic(sj) if isinstance(sj, dict) else sj for sj in j))  
        else:  
            setattr(top, i, j)  
    return top  
def byte_obj_decode_dic(obj_byte):  
    obj_json = str(xxx).replace('b\'','\'').replace('Namespace(','{').replace(')','}').replace('=',':').replace('\'','\"')
    dict = json.loads(obj_json)
    return dict
def byte_obj_decode_obj(obj_byte): 
    byte_obj_decode_dic(obj_byte)
    return dic2obj(obj_byte)

byte_obj_decode_dic是转换成dict,byte_obj_decode_obj是转成object,按需求取用即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值