2014-09-12 73 views
1

我在使用python 2.7讀取包含utf-8字符串的腳本時遇到了問題;在sitecustomize.py中將默認編碼設置爲utf-8似乎並不需要。python 2.7忽略解析腳本時在sitecustomize.py中設置的默認編碼

這裏是我的sitecustomize.py:

import sys 
sys.setdefaultencoding("utf-8") 

我可以確認的是,默認的編碼已在命令行中更改:

$ /usr/bin/python -c 'import sys; print(sys.getdefaultencoding())' 
utf-8 

然而,當我嘗試運行包含的腳本UTF-8字符串,如以下(含·在代碼點U + 00B7)test.py ...

filename = 'utf-8·filename.txt' 
print(filename) 

...的默認編碼似乎被忽略:

$ /usr/bin/python test.py 
    File "test.py", line 1 
SyntaxError: Non-ASCII character '\xc2' in file test.py on line 1, but 
no encoding declared; see http://www.python.org/peps/pep-0263.html for details 

使用的encoding declaration,如下test-coding.py ...

# coding=utf-8 
filename = 'utf-8·filename.txt' 
print(filename) 

... 確實工作:

$ /usr/bin/python test-coding.py 
utf-8·filename.txt 

不幸的是,問題出現了由另一個程序(catkin構建系統的catkin_make)生成並運行的腳本。在catkin_make運行之前,我無法手動向這些腳本添加編碼聲明,給出SyntaxError &檢查PEP 263。改變默認編碼看起來像是在catkin引擎蓋下深入的唯一解決方案,或者消除了我係統上的所有非ascii路徑......並將其設置在sitecustomize.py中應該可以工作,但不能。

任何想法或見解非常感謝!

+0

你爲什麼要在所有**處設置默認編碼**。你不應該那樣做。相反,修復你的Unicode處理代碼不要依賴默認編碼。 – 2014-09-12 18:40:21

+1

此外,系統默認編碼從不用於源文件。這是一個硬編碼的默認值。 – 2014-09-12 18:40:51

+0

我寧願使用編碼聲明,但腳本是由另一個程序(catkin構建系統的catkin_make)生成和運行的。在catkin_make運行之前,我無法手動向這些腳本添加編碼聲明。 – 2014-09-12 22:12:48

回答

0

您無法設置源文件的默認編碼。作爲語言規範的一部分,該默認是硬編碼的。

請設置PEP 263標題,因爲解釋器會指示您執行此操作。您必須修復Catkin構建系統,或重寫它生成的文件以包含標題。只需用# coding=utf8即可將這些文件的第一行或第二行添加到這些文件中,這是一項可輕鬆用Python完成的任務。

系統默認編碼僅爲用於對運行代碼中的Unicode和字節字符串對象進行隱式編碼和解碼。你不應該試圖改變這種情況,因爲其他人經常依靠價值觀來改變。設置它的能力完全從Python 3中刪除。

+0

聽起來好像沒有辦法隱含地說「對待所有文件,像他們說的那樣_#coding = utf8_」,這是一種恥辱。謝謝! – 2014-09-12 22:20:33

+0

@HonoreDoktorr Python 3會這樣做,但是這也需要語法上的改變。 – 2014-09-12 22:25:54

1

sys.setdefaultencoding("utf-8")沒有做你認爲它正在做的事情。它對Python解析源文件的方式沒有影響。這就是爲什麼當源文件使用非ascii字符時仍然看到SyntaxErrors。爲了消除那些你需要在源文件的開頭添加編碼聲明的錯誤,如

# -*- encoding: utf-8 -*- 

關於sys.setdefaultencoding

不要試圖改變默認編碼。Python在str 和unicode之間進行靜默轉換時使用默認編碼。例如,

預計Python2行爲:

In [1]: '€' + u'€' 

應該提高的UnicodeDecodeError因爲Python會嘗試把'€'通過 計算爲Unicode '€'.decode(sys.getdefaultencoding())

如果更改默認編碼,你會得到不同的行爲:

In [2]: import sys; reload(sys); sys.setdefaultencoding('utf-8') 
<module 'sys' (built-in)> 

In [3]: '€' + u'€' 
u'\u20ac\xe2\x82\xac' 

如果你改變了默認編碼,那麼你的Python的行爲將不同於其他人對Python2應該如何表現的期望。

+0

你是對的,我寧願把編碼聲明放在文件中,但腳本正在被另一個程序* catkin_make *生成並立即使用。在缺少我自己版本的catkin_make的情況下,我無法在腳本無法運行之前將它放在那裏。 – 2014-09-12 22:16:22

+0

這是[類似的錯誤報告](https://github.com/ros/catkin/issues/476)。我想你可能需要與坎昆開發者討論你的問題,以便乾淨地解決它(沒有黑客脆弱)。 – unutbu 2014-09-12 22:42:17