yacs + merge_from_file + UnicodeDecodeError: ‘gbk‘ codec can‘t decode xx: illegal multibyte sequence
Reason:
最近在学习yacs,在编写yaml文件时某个参数使用了中文字符。当我在py文件中引用这个参数时,出现了如下的错误:UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xa2 in position 262: illegal multibyte sequence,大体意思就是说gbk编码无法解码这个byte,这个byte是非法的多字节序列。简言之就是无法解码这个中文。
整个流程:
1、在一个defaults.py文件中编写几个cfgNode(就是Node),每个Node底下有自己的属性,并且给这些属性赋初值。赋完值之后,就可以在别外的py文件中引用Node底下的值。(红色框是对这个cfgNode结构的解释,即要先建一个根节点,之后可以在根节点上创建叶子节点或者非叶子节点,只有叶子节点可以赋值)
2、假设你想修改这些属性的值,那么可以直接修改defaults.py文件中某些Node的属性值,也可以通过yaml文件来间接修改。
3、我选择用yaml来修改。具体步骤是:编写yaml文件,编写文件的方式和cfgNode类似。对比上面两张图,可以轻易的看出映射关系(就是按名字映射)。
4、写完yaml文件,还不能修改defaults.py中的数,需要在使用它的py文件中加一句cfg.merge_from_file(‘xxxxxx.yaml’)
5、这时候,我想显示一下cfg.PLT.XLABEL,结果报错了不用想,肯定是yaml中的中文的问题。上网查找相关解决方法,他们的意思是在打开yaml文件的时候选择编码方式。
可我的代码中没有打开文件的代码(如 open(filename,‘r’)),但是观察错误信息,可以看到,merge_from_file在内部调用了open()方法:如图
这里open没有指定编码方式,其默认的编码方式是跟平台有关的,我用的是Windows,默认用gbk,所以这就找到了问题所在了。
解决办法就是在open函数中添加上encoding = ‘UTF-8’
6、再次运行,就会打印出中文:如图(忽略红色错误,跟本文没关系)
这篇博客是我记录错误是如何解决的,具体的细节,比如具体的py文件、py文件之间的相互调用,我没仔细写。如果问的人多的话,我会写的~