【原創】python中文編碼問題深入分析(二):print打印中文異常及顯示亂碼問題分析與解決


  在學習python以及在使用python進行項目開發的過程中,經常會使用print語句打印一些調試信息,這些調試信息中往往會包含中文,如果你使用python版本是python2.7,或許你也會遇到和我一樣的問題:那就是print打印中文異常以及顯示亂碼問題。本文主要分析一下在linux下使用python2.7的print語句中文異常以及終端顯示中文亂碼問題的原因及解決辦法。轉載請注明出處,謝謝!

  1.print打印顯示的過程

             

                                     圖1. Print打印顯示過程

  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):

      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,因此導致了亂碼。

               

       解決方法就是要保持終端編碼和待顯示的變量的編碼方式的一致。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM