概述
问题起因
这个问题的起因是我需要在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,按需求取用即可。
最后
以上就是无聊龙猫为你收集整理的解码python中byte编码的object的全部内容,希望文章能够帮你解决解码python中byte编码的object所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复