讓咱們先來看一個示例,源碼文件是utf-8格式:html
print('你好 python')
當使用python2執行該程序時會收到一下報錯:python
File "./hello_world.py", line 2 SyntaxError: Non-ASCII character '\xe4' in file ./hello_world.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
錯誤提示的意思就是存在非ASCII字符,可是卻沒有encoding declared,同時給了一個鏈接並說明包含詳細緣由,這個連接是一個PEP(python enhancement proper)。
編碼
這個PEP的內容總結下來就是:
這行代碼用於聲明代碼文件的編碼格式,這個信息能夠幫助python解析器使用指定的正確編碼來解釋代碼文件。這樣就能夠容許直接在代碼中使用utf-8編碼了。
另外須要注意的是:聲明的編碼格式要和代碼文件的格式同樣才行,不然會報錯。code
來看另一個例子:htm
# -*- coding:utf-8 -*- print('你好 python')
將這段代碼保存爲ANSI格式,並執行,會獲得如下報錯:ip
$ python ./hello_python.py File "./hello_python.py", line 2 SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte
因此說指定編碼的時候也不能所有統一指定爲utf-8,而是要根據源碼文件的格式來指定,二者要一致才行。utf-8
另外又在python的官方文檔找到一個說明:
意思就是說:默認狀況下,python解釋器(python2)把源代碼文件當作ASCII編碼來處理,若是源碼文件是其餘格式就須要經過一個特殊的註釋來講明,也就是:coding:utf-8,固然編碼格式支持多中,具體看codecs的支持狀況。
這裏其實也是因爲python誕生的太早了,那時候Unicode都尚未誕生,所以當時做者也只能選擇ASCII做爲默認的編碼格式。python3已經將默認編碼格式改成UTF-8ci
因此總結下來就是,python2中,該行代碼的做用是當源代碼文件不是ASCII編碼時,經過該行代碼告訴python解釋器正確的編碼格式,這樣python解釋器才能正常解釋其中的字符。
另外,因爲python3已經修改成默認狀況下,將源代碼文件當作UTF-8格式來處理,同時咱們寫代碼時如今一般都會使用UTF-8格式來存儲,所以python3實際上是不用再寫這一行代碼的,除非你的源代碼文件不是UTF-8格式的。unicode
先來看一個例子:文檔
# -*- coding:utf-8 -*- s = '你好' s.encode('gb2312')
執行以上代碼會收到下面的報錯:
Traceback (most recent call last): File "./hello_str.py", line 3, in <module> s.encode('gb2312') UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
第一次遇到這個報錯時,感受很奇怪,明明我作的是encode操做,可是爲何報錯確實decode失敗呢?
這裏就是先提一下了:Python裏面的編碼和解碼也就是unicode和str這兩種形式的相互轉化。編碼是unicode->str,相反的,解碼就是str->unicode。
而上面定義的s是str類型的,所以當調用encode時,其實默認是先作了decode,轉換爲Unicode,而後再執行encode編碼爲指定的編碼的,這裏報錯的緣由就是當作隱式編碼、解碼時使用的默認格式是:ASCII,可是因爲s是utf-8的編碼,因此解碼就失敗了。
解決辦法:
一、在文件頭部添加sys.setdefaultencoding('utf-8')修改默認的編碼、解碼格式。
import sys sys.setdefaultencoding('utf-8')
二、避免由程序作隱式的編碼、解碼,也就是說要明確str-Unicode的轉換規則,可是須要編碼時要確認類型是Unicode,若是不是就手動指定正確的解碼格式轉換爲Unicode。
s.decode('utf-8').encode('gb2312')
setdefaultencoding主要在編碼、解碼沒有明確指明編碼、解碼格式的時候使用。