2010-08-24 71 views
1

我在寫一個python3程序,它從命令行參數中獲取要處理的文件的名稱。我很困惑什麼是處理不同編碼的正確方法。命令行參數作爲字節,而不是python3中的字符串

我想我寧願把文件名視爲字節而不是字符串,因爲這避免了使用不正確編碼的危險。事實上,我的一些文件名使用不正確的編碼(當我的系統語言環境使用utf-8時,latin1),但這並不妨礙像ls這樣的工具正常工作。我希望我的工具能夠很好地恢復。

我有兩個問題:命令行參數作爲字符串(我使用argparse)給予我,並且我想以字符串的形式向用戶報告錯誤。

我成功地調整了我的代碼以使用二進制文件,並且我的工具可以處理當前默認編碼中名稱無效的文件,只要它是通過遞歸通過文件系統,因爲我將參數轉換爲二進制文件,並在調用fs函數時使用二進制文件。然而,當我收到一個無效的文件名參數時,它會以一個帶有奇怪字符(如\udce8)的unicode字符串形式提交給我。我不知道這些是什麼,並試圖編碼它總是失敗,無論是utf8還是相應的(錯誤的)編碼(這裏是latin1)。

另一個問題是報告錯誤。我希望我的工具的用戶解析我的stdout(因此希望保留文件名),但是在stderr上報告錯誤時,我寧願將其編碼爲utf-8,用適當的「無效/問號」字符替換無效序列。

所以,

1)有沒有更好的,完全不同的方式來做到這一點? (是的,修復文件名是有計劃的,但我仍然喜歡我的工具是健壯的)

2)我如何獲得它們的原始二進制形式的命令行參數(不爲我預先解碼)對於無效序列,重新編碼解碼後的參數將失敗,並且

3)如何告訴utf-8編解碼器用一些無效標記替換無效的,不可解碼的序列而不是死在我身上?

回答

2

當我收到一個文件名參數 這是無效的,但是,它是 交給我作爲一個Unicode字符串與 奇怪的字符,如\ udce8。

那些是替代字符。低8位是原始無效字節。

參見PEP 383: Non-decodable Bytes in System Character Interfaces

+0

好的,這表明點n°2。所以正確的方法是隻在我編碼CLI參數時添加'surrogateescape'?或者使用代理設施將所有內容作爲字符串處理?其他要點呢? – b0fh 2010-08-24 15:25:57

+0

至少我最關心的是解決,所以答案接受! – b0fh 2010-08-25 13:58:09

+0

Python 3.1(但不是3.0)應自動處理surrogateescape。只要將文件名視爲字符串即可。 – dan04 2010-08-25 14:42:08

-1

不要違背穀物:文件名是字符串,而不是字節。如果您使用string,則不應使用bytes。 A bytes是整數的元組。 A string是一個字符元組。他們是不同的概念。你在做什麼就像在使用布爾值時使用整數。 (另外:Python在Unicode中存儲內存中的所有字符串;所有字符串都以相同方式存儲。Encoding指定Python如何將文件字節轉換爲內存中的格式。)

您的操作系統將文件名存儲爲特定編碼下的字符串。我很驚訝你說一些文件名有不同的編碼;據我所知,文件名編碼是系統範圍的。例如,open等功能默認爲默認的系統文件名編碼。

+2

我希望我的操作系統將文件名視爲字符串,但有很多暗示情況並非如此。我嘗試使用不同的語言環境設置運行ls,它仍然支持相同的字節順序。如果區域設置與文件系統編碼不同,則不執行轉碼。 – b0fh 2010-08-25 07:50:11

+0

我曾經在任何地方使用過字符串(這就是我首先做的),但它不起作用,現在我認爲原因是我使用的一個庫(pyxattr)在處理代理時失敗。 – b0fh 2010-08-25 07:57:39

相關問題