Python2.7中文亂碼常見問題FAQ

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。只需要轉換成strunicode就可以了。

例子:

# 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!')

參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章