####1. Python源代碼文件的執行過程
我們都知道,磁盤上的文件都是以二進制格式存放的,其中文本文件都是以某種特定編碼的字節形式存放的。對于程序源代碼文件的字符編碼是由編輯器指定的,比如我們使用Pycharm來編寫Python程序時會指定工程編碼和文件編碼為UTF-8,那么Python代碼被保存到磁盤時就會被轉換為UTF-8編碼對應的字節(encode過程)后寫入磁盤。當執行Python代碼文件中的代碼時,Python解釋器在讀取Python代碼文件中的字節串之后,需要將其轉換為UNICODE字符串(decode過程)之后才執行后續操作。
上面已經解釋過,這個轉換過程(decode,解碼)需要我們指定文件中保存的字節使用的字符編碼是什么,才能知道這些字節在UNICODE這張萬國碼和統一碼中找到其對應的代碼點是什么。這里指定字符編碼的方式大家都很熟悉,如下所示:
# -*- coding:utf-8 -*-
2. 默認編碼
那么,如果我們沒有在代碼文件開始的部分指定字符編碼,Python解釋器就會使用哪種字符編碼把從代碼文件中讀取到的字節轉換為UNICODE代碼點呢?就像我們配置某些軟件時,有很多默認選項一樣,需要在Python解釋器內部設置默認的字符編碼來解決這個問題,這就是文章開頭所說的“默認編碼”。因此大家所說的Python中文字符問題就可以總結為一句話: 當無法通過默認的字符編碼對字節進行轉換時,就會出現解碼錯誤(UnicodeEncodeError) 。
Python2和Python3的解釋器使用的默認編碼是不一樣的,我們可以通過sys.getdefaultencoding()來獲取默認編碼:
>> > # Python2
>> > import sys
>> > sys.getdefaultencoding()
'ascii'
>> > # Python3
>> > import sys
>> > sys.getdefaultencoding()
'utf-8'
因此,對于Python2來講,Python解釋器在讀取到中文字符的字節碼嘗試解碼操作時,會先查看當前代碼文件頭部是否有指明當前代碼文件中保存的字節碼對應的字符編碼是什么。如果沒有指定則使用默認字符編碼"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來講,執行過程是一樣的,只是Python3的解釋器以"UTF-8"作為默認編碼,但是這并不表示可以完全兼容中文問題。比如我們在Windows上進行開發時,Python工程及代碼文件都使用的是默認的GBK編碼,也就是說Python代碼文件是被轉換成GBK格式的字節碼保存到磁盤中的。Python3的解釋器執行該代碼文件時,試圖用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. 最佳實踐
- 創建一個工程之后先確認該工程的字符編碼是否已經設置為UTF-8
- 為了兼容Python2和Python3,在代碼頭部聲明字符編碼:
-*- coding:utf-8 -*-
-
編碼
+關注
關注
6文章
935瀏覽量
54762 -
python
+關注
關注
56文章
4782瀏覽量
84453
發布評論請先 登錄
相關推薦
評論