python2因为编码的问题,导致包含中文文件的在python3上可以正常运行的程序,在python2上无法正常运行。
我遇到的主要是下面三种问题:
1.代码注释或者导入的文件名等有中文,无法识别
SyntaxError: Non-ASCII character '\xe5' in file ../utils/load_data.py on line 11, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
出错的原因是编码的方式,Python2中默认使用ascii,Python3中默认使用utf-8,如果文件中出现了中文,比如注释或者文件名等地方有中文,python2就会报这个错误。
解决办法是在代码的第一行加
# coding:UTF-8
或者
# -*- coding:UTF-8 -*-
PS:UTF可以小写
这么做是为了声明编码方式为utf-8,就可以识别中文了。
PS:添加这句以后,代码中出现的中文就可以识别了,但是python2读取文件、写入文件、print中文等时候还会有问题。
2.设置默认编码方式
如果我们没有指明解码方式,python默认编码方式为ANSCII,但是ascii不能编码中文的,我们在第一行的位置,已经将源文件的编码方式设置成了utf-8,这时候再使用ascii解码就会出现问题,最好设置默认的编码为utf-8,不然还会出现编码错误,例如
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
这时可以在代码开始的地方,比如import结束后的位置添加下面两句
reload(sys)
sys.setdefaultencoding('utf-8')
看到别人的代码里有个很多的写法,这样python2,3都可以用了:
if sys.version_info[0] > 2:
is_py3 = True
else:
reload(sys)
sys.setdefaultencoding("utf-8")
is_py3 = False
3.读取中文文件的内容错误
python2的中文文件在python3上用open函数打开的时候,会出现错误:
for line in open(path, encoding='utf-8').readlines()
TypeError: 'encoding' is an invalid keyword argument for this function
因为python2的open是无法指定编码方式的,如果删除掉encoding='utf-8'就不会报错了,但是可能会有编码的错误,导致其实并没有读到正确的中文内容。这里有两种做法,一种是对内容逐行进行decode。
我在读取文件的时候,一个txt文件是用open打开的,一个csv文件是用pandas打开的,两个都出现了编码问题,导致无法匹配内容。pandas可以指定编码方式为utf-8,我这里由于环境里面没有pandas又不能乱动人家的环境,就全部用txt文件打开了,txt文件有几种解决方法:
这里解决方式一:
for line in open(path).readlines():
line.decode('utf-8').strip()
读取之后每行都decode 为utf-8,这里注意不是encode,而是decode,不然还是会报错:
vocab = [line.strip().encode('utf-8') for line in open(path).readlines()]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)
这里可以先看看你的中文文件的编码方式,确定你的文件本身是utf-8的。
查看方式为:用vim打开文件,然后在命令模式下输入:set fileencoding 回车,vim就会显示当前文件的编码方式
:set fileencoding
fileencoding=utf-8
PS:如果要修改文件编码方式为utf-8的话可以用指令
:set fileencoding=utf-8
解决方式二:
这种方式在python2,python3都能用,推荐。
import codes
with codecs.open(path, encoding='utf-8') as f:
lines = f.readlines()[1:] # 这里打开的是本来打算用pandas打开的csv文件,把标题那行去掉
用codes的open就可以指定打开文件的编码方式了,非常方便,而且python2,3都可以用,代码比较一致,推荐这种方式。
关于编码的原理等我参考下面的两个帖子,想看原理的可以看看
https://www.jb51.net/article/87739.htm
https://blog.csdn.net/liuweiyuxiang/article/details/83831184
PS:
python2中如果使用
print("a",a)
a的内容是中文的话,print的中文就会显示乱码。这里如果不写在一起,只print(a)的话就会正常了,或者去掉括号写成print "a",a 的话也会正常显示。如果print list的话,print整个list也会出现中文是乱码的情况,但是遍历list,然后一个一个print的话,又会正常显示中文。这里的原因我还不太清楚,只是一个个人经验,如果print显示有问题的话,可以这么解决。如果有人知道原理的话,麻烦告诉我一下,感谢。
我遇到的主要就是上面的三种问题。如果遇到这种代码python3可以运行,2不行,然后怀疑是中文编码问题导致的。可以上来先把三种方法都用上,应该就能解决大部分问题了。