【原創】python中文編碼問題深入分析(三):python2.7文件讀寫中文編碼問題


  上一篇文章介紹和分析了python2.7中使用print遇到的中文編碼問題的原因和解決方案,本篇主要介紹一下python2.7中執行文件讀寫可能遇到的編碼問題。

  1.文件讀取

   假如我們讀取一個文件,文件保存時,使用的編碼格式,決定了我們從文件讀取的內容的編碼格式,例如,新建一個文本文件test.txt, 編輯內容,保存的時候注意,編碼格式設定為gb2312,那么使用python讀取文件內容,方式如下:

復制代碼
f = open('test.txt','r') s = f.read() #讀取文件內容,如果是不識別的encoding格式(識別的encoding類型跟使用的系統有關),這里將讀取失敗 '''假設文件保存時以gb2312編碼保存''' u = s.decode('gb2312') #以文件保存格式對內容進行解碼,獲得unicode字符串 '''下面我們就可以對內容進行各種編碼的轉換了''' str = u.encode('utf-8')#轉換為utf-8編碼的字符串str strGbk = u.encode('gbk')#轉換為gbk編碼的字符串str1 
復制代碼

  注意:1)調用read()函數文件test.txt時,如果test.txt文件中不包含BOM信息(BOM信息一般是3個字節,用於標識文件的編碼格式),則系統會使用現在支持的文件編碼格式(utf-8,gbk等,優先使用utf-8,最后使用系統默認的編碼方式),嘗試着讀取和解析text.txt,如果能打開並解析成功(假設以gbk編碼方式能正確打開test.txt),那么s的編碼類型gbk 。

     2)如果open時使用的encoding和文件本身的encoding不一致的話,那么這里將將會產生錯誤

     3)s的類型為str

  此外,python提供了codecs包,可供進行文件的讀取,包中的open()函數可以指定文件編碼的類型:

import codecs f = codecs.open('text.text','r+',encoding='utf-8')#必須事先知道文件的編碼格式,這里文件編碼是使用的utf-8 content = f.read()#如果open時使用的encoding和文件本身的encoding不一致的話,那么這里將將會產生錯誤 f.write('你想要寫入的信息') f.close()

  注意:1)必須事先知道文件的編碼格式,這里文件編碼是使用的utf-8   2)如果open時使用的encoding和文件本身的encoding不一致的話,那么這里將將會產生錯誤

     3) content的類型為unicode。

 

  2.文件寫入 

    調用python文件寫入函數時,如果待寫入變量unStr是unicode類型,則系統首先使用系統的默認編碼方式,將unStr變量進行unicode編碼成str的類型,然后再寫入文件。

unStr=u"測試"
f = open('test.txt','w') f.write(unStr) #如果系統的默認編碼是asii,則會出現UnicodeEncodeError問題

    如果系統的默認編碼方式是ascii,則就會出現上文中提到的UnicodeEncodeError問題。解決方法有兩個:

    1) 首先獲取文件的默認編碼格式,執行write函數前,將unStr編碼成文件的默認編碼格式,例如:在我的機器上,創建一個新文件時,其文件編碼格式為utf-8,則修改f.write(unStr) f.write(unStr.encoding('utf-8'))。(建議選這一種)

    2) 修改系統的默認編碼方式為utf-8;

      3. 關於sys.setdefaultencoding()和sys.stdout.encoding()

        1) sys.setdefaultencoding()是str類型編解碼時默認使用的編碼格式,文件讀寫、str類型編碼,在不明確指定編碼格式的情況下均使用 sys.setdefaultencoding()

      #! /usr/bin/env python 
      # -*- coding: utf-8 -*- 
      s = '中文字符'  # 這里的 str 是 str 類型的,而不是 unicode 
      s.encode('gb2312') 

  這句代碼將 s 重新編碼為 gb2312 的格式,即進行 unicode -> str 的轉換。因為 s 本身就是 str 類型的,因此 Python 會自動的先將 s 解碼為 unicode ,然后再編碼成 gb2312。因為解碼是python自動進行的,我們沒有指明解碼方式,python 就會使用 sys.defaultencoding 指明的方式來解碼。很多情況下 sys.defaultencoding為ANSCII,如果 s 不是這個類型就會出錯。
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 
  0: ordinal not in range(128)

       2)sys.stdout.encoding() 是終端輸出的默認編碼格式,例如:print

    至此,python2.7中有關中文編碼的相關問題分析及解決已接近尾聲,由於筆者水平有限,難免出現錯誤和不當的地方,希望大家多多指正。

 


免責聲明!

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



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