【原創】Python 源文件編碼解讀

以下內容源於對 PEP-0263 的翻譯和解讀,同時給出了一些網上網友的說法。  

========  我是分割線 ========  

PEP 0263 -- Defining Python Source Code Encodings  

【摘要】  
      給出聲明 Python 源文件編碼的語法。該編碼信息後續會被 Python 解析器用於解析源文件。  
      這種方式增強了對源文件中 Unicode 編碼字的處理。  

【問題】  
      Python 2.1 時代,Unicode 字符只能利用 Latin-1 字符進行「Unicode 轉義」的方式來表示(也就是說當時只支持 Latin-1 字符編碼,所以 Unicode 字符編碼只能使用 Latin-1 字符來進行轉義表示)。這對廣大亞洲人民是很坑爹的。  

【解決方案】  
      通過在 Python 腳本文件的頭部增加 顯式的、可按文件隨時改變的 特殊註釋,來聲明編碼方式。  

【編碼定義】  
      Python 默認使用 ASCII 編碼。  
      若要自定義 Python 源碼的編碼方式,需要在腳本文件的第一或者第二行的位置上添加如下定義:  
1.  
?
1
# coding=<encoding name>
2.  
?
1
2
#!/usr/bin/python
# -*- coding: <encoding name> -*-
3.  
?
1
2
#!/usr/bin/python
# vim: set fileencoding=<encoding name> :
在前兩種方式中,實際上是通過 coding[:=]\s*([-\w.]+) 這個正則表達式來進行匹配。            

      爲了支持 Windows 平臺上的應用,會在生成的 Unicode 文件的頭部添加 Unicode BOM 標識,其中帶有 UTF-8 標識 '\xef\xbb\xbf' 的文件會被當做具有 UTF-8 編碼的文件(此時在 Python 腳本的頭部沒有那行編碼特殊註釋也沒問題) 。  

      如果出現源文件同時使用了 UTF-8 BOM 標識和文件頭部的特殊註釋的情況,那麼在表明編碼的特殊註釋中只能使用 'utf-8' 這個字串,其他情況會報錯。  

【舉例】  

1. Python 解析器說明 + Emacs 風格的文件編碼註釋  
?
1
2
3
4
#!/usr/bin/python
# -*- coding: latin-1 -*-
import os, sys
...
?
1
2
3
4
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import os, sys
...
?
1
2
3
4
#!/usr/bin/python
# -*- coding: ascii -*-
import os, sys
...

2. 無 Python 解析器說明 + 普通明文描述  
?
1
2
3
# This Python file uses the following encoding: utf-8
import os, sys
...

3. Python 解析器說明 + 非 Emacs 風格的文件編碼註釋  
?
1
2
3
4
#!/usr/local/bin/python
# coding: latin-1
import os, sys
...

4. 無編碼註釋(Python 解析器默認爲 ASCII)  
?
1
2
3
#!/usr/local/bin/python
import os, sys
...

5. 錯誤的編碼註釋方式  
a. 無 coding: 前綴  
?
1
2
3
4
#!/usr/local/bin/python
# latin-1
import os, sys
...
b. 編碼註釋不在第一或第二行  
?
1
2
3
4
5
#!/usr/local/bin/python
#
# -*- coding: latin-1 -*-
import os, sys
...
c. 使用不支持的編碼  
?
1
2
3
4
#!/usr/local/bin/python
# -*- coding: utf-42 -*-
import os, sys
...

=========== 我是分割線 ============  

小實驗截圖:
輸出中文。
 
 
報錯。 
添加編碼。 
 
正常輸出。 
 
IDE默認的編碼設置。 
 
各種轉碼輸出。 
 
輸出的結果。 
 

 

補充說明:  
cp936即 code page 936(代碼頁936)是以GBK(國標擴展字符集)爲基礎的編碼。GB2312(國標字符集)只是GBK的一部分。   GB2312只支持常用的漢字,而且是簡體字。GBK支持繁體字和生僻字。