#!/usr/bin/python
是用來說明腳本語言是python的
是要用/usr/bin下面的程序(工具)python,這個解釋器,來解釋python腳本,來運行python腳本的。
# -*- coding: utf-8 -*-
是用來指定文件編碼為utf-8的
詳情可以參考:
PEP 0263 — Defining Python Source Code Encodings
在此,詳細的(主要是翻譯)解釋一下,為何要加這個編碼聲明,以及如何添加編碼聲明:
使用文件編碼聲明以前所遇到的問題
Python 2.1中,想要輸入Unicode字符,只能用基於Latin-1的"unicode-escape"的方式輸入 -> 對於其他非Latin-1的國家和用戶,想要輸入Unicode字符,就顯得很繁瑣,不方便。
希望是:
編程人員,根據自己的喜好和需要,以任意編碼方式輸入字符串,都可以,這樣才正常。
建議選用的方案
所以,才有人給Python官方建議,所以才有此PEP 0263。
此建議就是:
允許在Python文件中,通過文件開始處的,放在注釋中的,字符串形式的,聲明,聲明自己的python文件,用何種編碼。
由此,需要很多地方做相應的改動,尤其是Python文件的解析器,可以識別此種文件編碼聲明。
具體如何聲明python文件編碼?
上面已經說了,是,文件開始處的,放在注釋中的,字符串形式的,聲明。
那具體如何聲明,以什么樣的格式去聲明呢?
其實就是,你之前就見過的,這種:
1
|
# -*- coding: utf-8 -*-
|
對此格式的詳細解釋是:
- 如果沒有此文件編碼類型的聲明,則python默認以ASCII編碼去處理
- 如果你沒聲明編碼,但是文件中又包含非ASCII編碼的字符的話,python解析器去解析的python文件,自然就會報錯了。
- 必須放在python文件的第一行或第二行
- 支持的格式,可以有三種:
- 帶等於號的:
1
# coding=<encoding name>
- 最常見的,帶冒號的(大多數編輯器都可以正確識別的):
12
#!/usr/bin/python
# -*- coding: <encoding name> -*-
- vim的:
12
#!/usr/bin/python
# vim: set fileencoding=<encoding name> :
- 帶等於號的:
- 更加精確的解釋是:
- 符合正則表達式:
1
"coding[:=]\s*([-\w.]+)"
- 的都可以,很明顯,如果你熟悉正則表達式,也就可以寫出來,其他一些合法的編碼聲明,以utf-8為例,比如:
12345
coding: utf
-
8
coding
=
utf
-
8
coding
=
utf
-
8
encoding:utf
-
8
crifanEncoding
=
utf
-
8
- 符合正則表達式:
- 為了照顧特殊的Windows中的帶BOM(’\xef\xbb\xbf’)的UTF-8:
- 如果你的python文件本身編碼是帶BOM的UTF-8,即文件前三個字節是:’\xef\xbb\xbf’,那么:
- 即使你沒有聲明文件編碼,也自動當做是UTF-8的編碼
- 如果你聲明了文件編碼,則必須是聲明了(和你文件編碼本身相一致的)UTF-8
- 否則(由於聲明的編碼和實際編碼不一致,自然)會報錯
- 如果你的python文件本身編碼是帶BOM的UTF-8,即文件前三個字節是:’\xef\xbb\xbf’,那么:
文件編碼聲明的各種例子
針對上面的規則,下面給出各種,合法的,非法的,例子,供參考:
合法的python文件編碼聲明
- 帶聲明了解釋器的,Emacs風格的,(注釋中的)文件編碼聲明
- 例子1:
1234
#!/usr/bin/python
# -*- coding: latin-1 -*-
import
os, sys
...
- 例子2:
1234
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import
os, sys
...
- 例子3:
1234
#!/usr/bin/python
# -*- coding: ascii -*-
import
os, sys
...
- 例子1:
- 不帶聲明了解釋器的,直接用純文本形式的:
123
# This Python file uses the following encoding: utf-8
import
os, sys
...
- 文本編輯器也可以有多種(其他的)定義編碼的方式:
1234
#!/usr/local/bin/python
# coding: latin-1
import
os, sys
...
- 很明顯,其中的沒用-*-,直接用了coding加上編碼值
- 不帶編碼聲明的,默認當做ASCII處理:
123
#!/usr/local/bin/python
import
os, sys
...
非法的python文件編碼聲明舉例
- 少了coding:前綴
1234
#!/usr/local/bin/python
# latin-1
import
os, sys
...
- 編碼聲明不在第一行或第二行:
12345
#!/usr/local/bin/python
#
# -*- coding: latin-1 -*-
import
os, sys
...
- 不支持的,非法的字符編碼(字符串)聲明:
1234
#!/usr/local/bin/python
# -*- coding: utf-42 -*-
import
os, sys
...
python文件編碼聲明所遵循的理念
1.單個的完整的python源碼文件中,只用單一的編碼。
->
不允許嵌入了多種的編碼的數據
否則會導致(python解釋器去解析你的python文件時)報編碼錯誤。
不太懂這段:
Any encoding which allows processing the first two lines in the way indicated above is allowed as source code encoding, this includes ASCII compatible encodings as well as certain multi-byte encodings such as Shift_JIS. It does not include encodings which use two or more bytes for all characters like e.g. UTF-16. The reason for this is to keep the encoding detection algorithm in the tokenizer simple. |
2.這段也不太懂:
Handling of escape sequences should continue to work as it does now, but with all possible source code encodings, that is standard string literals (both 8-bit and Unicode) are subject to escape sequence expansion while raw string literals only expand a very small subset of escape sequences. |
3.Python的分詞器+編譯器,會按照如下的邏輯去工作:
- 讀取文件
- 不同的文件,根據其聲明的編碼去解析為Unicode
- 轉換為UTF-8字符串
- 針對UTF-8字符串,去分詞
- 編譯之,創建Unicode對象
要注意的是:
Python中的標識符,都是ASCII的。
其余的內容,不翻譯了。
至此,已經解釋的夠清楚了。