python 中幾個層次的中文編碼.md

轉自:[http://swj.me/]python

介紹

一直不太喜歡使用命令行,因此去年年末的技術創新中,使用TkInter來開發小工具。結果花費了大量的時間來學習TkInter ui的使用。
最近想整理該工具,使用命令行的形式,而後將該工具作成exe的形式進行分發。在工做一開始就遇到了編碼的問題。
在腳本中有以下代碼,用來接收用戶交互式輸入的ip。windows

server = raw_input("請輸GIS Server IP:")

在腳本文件的第一行,我已經加了以下代碼工具

# -*-coding: utf-8 -*-

可是在windows 的控制檯執行的時候,出現了亂碼。有點不解,由於本身一直以來在python中,處理中文都是在文件頭加入該代碼。學習

經過搜索發現,是由於在windows cmd 默認的使用的cp936的編碼。既然知道使用這種編碼則將編碼改成以下:測試

# -*-coding: cp936-*-

可是獲得以下的錯誤:ui

SyntaxError: encoding problem: cp936 with BOM

百思不得其解。做爲懶癌患者,就想繞過去。則採用以下方式,對單獨字符串進行編碼。編碼

userName=raw_input("請輸入站點管理員用戶名:".decode("utf-8").encode("cp936"))

這樣重要在cmd中能夠正常的輸出中文了。可是問題來了,個人腳本中,有上百行代碼有中文。每一個地方都這麼寫,感受偷懶不成,反被*。
這個時候,經過搜索。逐步的發現了問題的緣由。這是由於python有幾個層次的編碼。分別是:命令行

  • 字符串變量級別編碼
  • 腳本級別的編碼
  • py文件級別的編碼
  • 顯示窗口的編碼

字符串變量的編碼

對單個字符串轉碼,可使用:encode()編碼成能夠顯示的。一般對字符串不能由一個編碼直接轉換爲另外一個編碼。一般須要解碼到Unicode,而後對unicode字符串從新的編碼。好比上面的示例。code

腳本的編碼

上面經過設置 #coding:utf-8設置的就是腳本里面內容的編碼。也就是該腳本文件中全部的字符串變量都採用該處設置的編碼方式。server

py文件的編碼

py文件的編碼,默認的是ANSI。可是也可使用utf-8,unicode編碼。

顯示窗口的編碼

上面的幾種狀況,中文在運行階段不會出錯。可是這些中文還不必定可以正常的顯示。可否正常的顯示,還有顯示窗口支持的編碼決定。好比cmd中中文支持GBK和cp936,因此代碼中的字符串須要編碼到這兩種才能夠顯示。

測試

  1. 當py文件的編碼爲utf-8的時候。代碼中唔須要添加#coding:utf-8 。腳本中的中文,在運行過程不會報錯。
  2. 當py文件的編碼爲ANSI的時候。如代碼中沒有顯示的添加 ** --coding:utf-8 -- **,則當代碼中出現中文的時候,運行腳本的時候。會出現以下錯誤
SyntaxError: Non-ASCII character '\xe4' in file
  1. 當py文件設置爲utf-8,而顯示設置代碼編碼爲#coding:936。則會出現ncoding problem: cp936 with BOM的錯。這個時候,將py文件的編碼改成ANSI便可。

結論

經過上面的測試,有幾個結論:

  1. 編碼有層次結構。文件編碼影響腳本內容編碼,腳本內容編碼決定 其中的字符串編碼。
  2. 當字符串顯示設置了編碼的時候。字符串的編碼爲顯示設置的編碼,此時文件和腳本編碼不起做用。當字符串沒有顯示設置編碼的時候,則採用上一級編碼決定。
  3. 因此設置這三種編碼的時候,須要確保三種編碼之間可以轉換。不然會出現上面列舉的錯誤。
相關文章
相關標籤/搜索