關於Python腳本開頭兩行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 轉


#!/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 -*-

對此格式的詳細解釋是:

  1. 如果沒有此文件編碼類型的聲明,則python默認以ASCII編碼去處理
    • 如果你沒聲明編碼,但是文件中又包含非ASCII編碼的字符的話,python解析器去解析的python文件,自然就會報錯了。
  2. 必須放在python文件的第一行或第二行
  3. 支持的格式,可以有三種:
    1. 帶等於號的:
      ?
      1
      # coding=<encoding name>
    2. 最常見的,帶冒號的(大多數編輯器都可以正確識別的):
      ?
      1
      2
      #!/usr/bin/python
      # -*- coding: <encoding name> -*-
    3. vim的:
      ?
      1
      2
      #!/usr/bin/python
      # vim: set fileencoding=<encoding name> :
  4. 更加精確的解釋是:
    • 符合正則表達式:
      ?
      1
      "coding[:=]\s*([-\w.]+)"
    • 的都可以,很明顯,如果你熟悉正則表達式,也就可以寫出來,其他一些合法的編碼聲明,以utf-8為例,比如:
      ?
      1
      2
      3
      4
      5
      coding:         utf - 8
      coding = utf - 8
      coding =                  utf - 8
      encoding:utf - 8
      crifanEncoding = utf - 8
  5. 為了照顧特殊的Windows中的帶BOM(’\xef\xbb\xbf’)的UTF-8
    1. 如果你的python文件本身編碼是帶BOM的UTF-8,即文件前三個字節是:’\xef\xbb\xbf’,那么:
      1. 即使你沒有聲明文件編碼,也自動當做是UTF-8的編碼
      2. 如果你聲明了文件編碼,則必須是聲明了(和你文件編碼本身相一致的)UTF-8
        1. 否則(由於聲明的編碼和實際編碼不一致,自然)會報錯

 

文件編碼聲明的各種例子

針對上面的規則,下面給出各種,合法的,非法的,例子,供參考:

合法的python文件編碼聲明

  1. 帶聲明了解釋器的,Emacs風格的,(注釋中的)文件編碼聲明
    1. 例子1:
      ?
      1
      2
      3
      4
      #!/usr/bin/python
      # -*- coding: latin-1 -*-
      import os, sys
      ...
    2. 例子2:
      ?
      1
      2
      3
      4
      #!/usr/bin/python
      # -*- coding: iso-8859-15 -*-
      import os, sys
      ...
    3. 例子3:
      ?
      1
      2
      3
      4
      #!/usr/bin/python
      # -*- coding: ascii -*-
      import os, sys
      ...
  2. 不帶聲明了解釋器的,直接用純文本形式的:
    ?
    1
    2
    3
    # This Python file uses the following encoding: utf-8
    import os, sys
    ...
  3. 文本編輯器也可以有多種(其他的)定義編碼的方式:
    ?
    1
    2
    3
    4
    #!/usr/local/bin/python
    # coding: latin-1
    import os, sys
    ...
    • 很明顯,其中的沒用-*-,直接用了coding加上編碼值
  4. 不帶編碼聲明的,默認當做ASCII處理:
    ?
    1
    2
    3
    #!/usr/local/bin/python
    import os, sys
    ...

非法的python文件編碼聲明舉例

  1. 少了coding:前綴
    ?
    1
    2
    3
    4
    #!/usr/local/bin/python
    # latin-1
    import os, sys
    ...
  2. 編碼聲明不在第一行或第二行:
    ?
    1
    2
    3
    4
    5
    #!/usr/local/bin/python
    #
    # -*- coding: latin-1 -*-
    import os, sys
    ...
  3. 不支持的,非法的字符編碼(字符串)聲明:
    ?
    1
    2
    3
    4
    #!/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的分詞器+編譯器,會按照如下的邏輯去工作:

  1. 讀取文件
  2. 不同的文件,根據其聲明的編碼去解析為Unicode
  3. 轉換為UTF-8字符串
  4. 針對UTF-8字符串,去分詞
  5. 編譯之,創建Unicode對象

要注意的是:

Python中的標識符,都是ASCII的。

 

其余的內容,不翻譯了。

至此,已經解釋的夠清楚了。

 
原文鏈接:http://www.crifan.com/python_head_meaning_for_usr_bin_python_coding_utf-8/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM