Python2.x中的str
类型并不是真正意义上的字符串,而更像是一个bytes(字节码串),超出ASCII码范围的字符时会出现乱码。
在Python3.x中已经解决这个问题,str
就是真正意义上的字符串。
Q: Python源文件中含有中文时运行报错:
SyntaxError: Non-ASCII character … but no encoding declared
A: 在Python文件开头声明UTF-8编码:
# encoding=utf-8
print('人生苦短,我用Python!')
Q: 在Python文件开头声明UTF-8编码后,仍然打印乱码。
A: 需要将str
转换成unicode
类型再打印。
# encoding=utf-8
print(u'人生苦短,我用Python!')
print('人生苦短,我用Python!'.decode('utf-8'))
print(unicode('人生苦短,我用Python!', 'utf-8'))
Q: 写入文件时,文件名乱码:
# encoding=utf-8
with open('测试.txt', 'w' ) as test_file:
test_file.write('人生苦短, 我用Python!')
A: 将文件名从str
类型转换为unicode
类型:
# encoding=utf-8
with open('测试.txt'.decode('utf-8'), 'w' ) as test_file:
test_file.write('人生苦短, 我用Python!')
Q: 写入文件和格式化等操作时报UnicodeEncodeError错误:
UnicodeEncodeError: ‘ascii’ codec can’t encode characters
A: 原因是在需要传入str
时候,传入了unicode
;或者在需要传入unicode
时候,传入了str
。只需要转换成str
或unicode
就可以了。
例子:
# encoding=utf-8
s = '人生苦短,我用Python!'
print(type(s))
# 将str转为unicode
print(type(s.decode('utf-8')))
print(type(u'人生苦短,我用Python!'))
print(type(unicode(s, 'utf-8')))
# 将unicode转为str
code = unicode(s, 'utf-8')
print(type(code.encode('utf-8')))
print(type(b'人生苦短,我用Python!'))
Q: Python2的open()函数打开文件时,每一行是str
类型,传入unicode
时出错。
A: 使用io.open()
函数打开文件,每一行是unicode
类型。
Q: 文件内容乱码
A: 这个和Python2.x的字符串表示方法无关,只需要指定正确文件格式编码(file encoding)就可以,比如utf-8, gbk等。
Q: 在写入文件时,已经使用gbk
编码,但是有时仍然会报错:
UnicodeDecodeError: ‘gbk’ codec can’t decode … illegal multibyte sequence
A:这是因为写入的文本中含有超出gbk编码的范围,可以尝试换成其他编码,比如gb18030或utf-8等。简单来说中文编码包含字符集的范围是: GB18030 > GBK > GB2312。更安全的写法在打开文件时,传入参数errors='ignore'
忽略编码错误(默认为strict模式):
with io.open(file_name, 'w', encoding='gb18030', errors='ignore') as test_file:
另外说一个Notepad++的小坑,有时候一个中文文件用Windows自带的Notepad可以正常打开,但是用Notepad++打开却会乱码,即使换成UTF-8也会乱码,这时需要换成ANSI(微软的编码解决方案,不是一种编码,也不是ASCII码)。这是因为文件中含有超出了GB2312(Notepad++默认中文简体编码)和UTF-8的编码,而微软的ANSI却能支持这些超出范围的编码。
Q:讨厌写encode()和decode(),有没有更简单的方法?
A: 使用__future__
的unicode_literals
,可以在不升级到Python3.x,就可以使用Python3.x的unicode编码特性:
# encoding=utf-8
from __future__ import unicode_literals
import io
print('人生苦短,我用Python!')
with io.open('测试.txt', 'w', encoding='utf-8') as test_file:
test_file.write('人生苦短, 我用Python!')
__future__