文章目錄
Python2.7中文亂碼常見問題FAQ
萬惡之源
Python2.x中的str
類型並不是真正意義上的字符串,而更像是一個bytes(字節碼串),超出ASCII碼範圍的字符時會出現亂碼。
在Python3.x中已經解決這個問題,str
就是真正意義上的字符串。
FAQ
Python源文件中含有中文時運行出錯
Q: Python源文件中含有中文時運行報錯:
SyntaxError: Non-ASCII character … but no encoding declared
A: 在Python文件開頭聲明UTF-8編碼:
# encoding=utf-8
print('人生苦短,我用Python!')
在Python文件開頭聲明UTF-8編碼後,仍然打印亂碼
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!')
UnicodeEncodeError錯誤
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等。
Illegal multibyte sequence
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卻能支持這些超出範圍的編碼。
討厭encode()和decode()
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!')