在學習python以及在使用python進行項目開發的過程當中,常常會使用print語句打印一些調試信息,這些調試信息中每每會包含中文,若是你使用python版本是python2.7,或許你也會遇到和我同樣的問題:那就是print打印中文異常以及顯示亂碼問題。本文主要分析一下在linux下使用python2.7的print語句中文異常以及終端顯示中文亂碼問題的緣由及解決辦法。轉載請註明出處,謝謝!python
1.print打印顯示的過程linux
圖1. Print打印顯示過程python2.7
Python2.7中調用print打印var 變量時,操做系統會對var作必定的字符處理:若是var是str類型的變量,則直接將var變量交付給終端進行顯示;若是var變量是unicode類型,則操做系統首先將var編碼成str類型的對象(編碼格式取決於stdout的編碼格式),而後再交由終端進行顯示。在終端顯示時,若是str類型的變量的編碼方式和終端設置的編碼方式不一致,極可能會出現亂碼問題。函數
2.print中文字符出現錯誤問題學習
在python源碼中print中文字符,時常會出現Non-ASCII character和UnicodeEncodeError兩類錯誤。下面分別一一介紹。測試
2.1 Non-ASCII character錯誤編碼
print.py源碼示例(代碼1):spa
import sys操作系統
print sys.getdefaultencoding()調試
a="測試"
b=u"測試"
print a
print b
這段代碼試圖在linux的終端打印變量a和b的值,可是在實際執行的過程當中,會提示Non-ASCII character錯誤:
緣由:該print.py的文件格式是utf-8(能夠vi print.py,而後在命令模式下,輸入:set fileencoding,查看文件的編碼方式,)。「測試」對應的utf-8編碼爲:'\xe6\xb5\x8b\xe8\xaf\x95',因爲print.py中含有中文,且print.py沒有指定編碼方式,python會按照系統的默認編碼解析執行print.py(這裏的系統默認編碼是ascii,查看系統的默認編碼,能夠調用sys.getdefaultencoing()函數),所以會提示Non-ASCII character的錯誤。
解決辦法:在print.py起始處,指定編碼方式爲utf-8,這樣python在執行代碼時,就知道要按照utf-8來解釋執行代碼了。代碼2:
#coding=utf-8
import sys
print sys.getdefaultencoding()
a="測試"
b=u"測試"
print a
print b
運行結果以下:
2.2 UnicodeEncodeError問題
代碼2在192.168.86.61上能正常運行,可是換到另外一臺機器192.168.86.157就不能正常運行了,現象以下:
從打印信息來看,print a能夠正常輸出,而print b就會出現UnicodeEncodeError錯誤,這是爲何呢??
根據第1節中的介紹,變量b是unicode類型的,操做系統會按照stdout的默認編碼將b編碼成str類型的變量,根據報錯信息猜想系統stdout的默認編碼是ascii,而ascii字符的範圍是0-127,所以會報上述錯誤。而變量a是str類型,調用print時,不須要通過操做系統進行編碼,因此能正常輸出。
那麼,如何驗證157上的系統stdout的編碼方式是否是ascii呢?能夠經過sys.stdout.encoding查看stdout的編碼方式,這裏的輸出結果是ANSI_X3.4-1968,其別名就是ASCII,哈哈,原來真的是這樣。
那麼,爲何在192.168.86.61上,print b就能正常被打印輸出呢?想要知道緣由,讓咱們查看一下192.168.86.61上的stdout的編碼方式,經過sys.stdout.encoding查得stdout的編碼方式爲utf-8,unicode類型的變量b的print時,首先被編碼成utf-8,而後在送至終端顯示,一切正常!
至此,你可能明白了該問題產生的緣由,那麼,這個問題該怎麼解決呢?通常建議在調用print打印變量時,首先調用encode()函數將unicode類型的變量進行編碼,轉換成str類型的變量,代碼3以下:
#coding=utf-8
import sys
print sys.getdefaultencoding()
a="測試"
b=u"測試"
print a
print b.encode('utf-8')
以後,程序能夠正常運行,以下:
3.linux終端顯示中文亂碼
第1節中曾提到過:若是str類型的變量的編碼方式和終端設置的編碼方式不一致,在終端顯示時就會出現中文亂碼問題。筆者使用的終端的編碼方式爲utf-8,以下圖:
若是將終端的編碼方式改成GB2312,則中文就會出現亂碼。由於b.encode('utf-8')的編碼爲utf-8,而終端的爲GB2312,所以致使了亂碼。
解決方法就是要保持終端編碼和待顯示的變量的編碼方式的一致。