####1. Python源代碼文件的執(zhí)行過程
我們都知道,磁盤上的文件都是以二進制格式存放的,其中文本文件都是以某種特定編碼的字節(jié)形式存放的。對于程序源代碼文件的字符編碼是由編輯器指定的,比如我們使用Pycharm來編寫Python程序時會指定工程編碼和文件編碼為UTF-8,那么Python代碼被保存到磁盤時就會被轉換為UTF-8編碼對應的字節(jié)(encode過程)后寫入磁盤。當執(zhí)行Python代碼文件中的代碼時,Python解釋器在讀取Python代碼文件中的字節(jié)串之后,需要將其轉換為UNICODE字符串(decode過程)之后才執(zhí)行后續(xù)操作。
上面已經解釋過,這個轉換過程(decode,解碼)需要我們指定文件中保存的字節(jié)使用的字符編碼是什么,才能知道這些字節(jié)在UNICODE這張萬國碼和統(tǒng)一碼中找到其對應的代碼點是什么。這里指定字符編碼的方式大家都很熟悉,如下所示:
# -*- coding:utf-8 -*-
2. 默認編碼
那么,如果我們沒有在代碼文件開始的部分指定字符編碼,Python解釋器就會使用哪種字符編碼把從代碼文件中讀取到的字節(jié)轉換為UNICODE代碼點呢?就像我們配置某些軟件時,有很多默認選項一樣,需要在Python解釋器內部設置默認的字符編碼來解決這個問題,這就是文章開頭所說的“默認編碼”。因此大家所說的Python中文字符問題就可以總結為一句話: 當無法通過默認的字符編碼對字節(jié)進行轉換時,就會出現解碼錯誤(UnicodeEncodeError) 。
Python2和Python3的解釋器使用的默認編碼是不一樣的,我們可以通過sys.getdefaultencoding()來獲取默認編碼:
>> > # Python2
>> > import sys
>> > sys.getdefaultencoding()
'ascii'
>> > # Python3
>> > import sys
>> > sys.getdefaultencoding()
'utf-8'
因此,對于Python2來講,Python解釋器在讀取到中文字符的字節(jié)碼嘗試解碼操作時,會先查看當前代碼文件頭部是否有指明當前代碼文件中保存的字節(jié)碼對應的字符編碼是什么。如果沒有指定則使用默認字符編碼"ASCII"進行解碼導致解碼失敗,導致如下錯誤:
SyntaxError: Non-ASCII character '\\xc4' in file xxx.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
對于Python3來講,執(zhí)行過程是一樣的,只是Python3的解釋器以"UTF-8"作為默認編碼,但是這并不表示可以完全兼容中文問題。比如我們在Windows上進行開發(fā)時,Python工程及代碼文件都使用的是默認的GBK編碼,也就是說Python代碼文件是被轉換成GBK格式的字節(jié)碼保存到磁盤中的。Python3的解釋器執(zhí)行該代碼文件時,試圖用UTF-8進行解碼操作時,同樣會解碼失敗,導致如下錯誤:
SyntaxError: Non-UTF-8 code starting with '\\xc4' in file xxx.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
3. 最佳實踐
- 創(chuàng)建一個工程之后先確認該工程的字符編碼是否已經設置為UTF-8
- 為了兼容Python2和Python3,在代碼頭部聲明字符編碼:
-*- coding:utf-8 -*-
-
編碼
+關注
關注
6文章
932瀏覽量
54731 -
python
+關注
關注
55文章
4767瀏覽量
84376
發(fā)布評論請先 登錄
相關推薦
評論