2011-09-09 40 views
3

我有一個python程序運行得很好。它連接到幾個網站並輸出所需的信息。由於並非所有網站都使用utf-8進行編碼,因此我正在從頭文件請求字符集,並使用unicode(string, encoding)方法進行解碼(我不確定是否採用適當的方式來完成此操作,但工作得很好)。當我運行python程序時,我收不到?標記和它工作正常。但是,當我運行使用PHP的system功能的程序,我收到此錯誤:php系統,蟒蛇和utf-8

UnicodeEncodeError: 'ascii' codec can't encode character u'\u0131' in position 41: ordinal not in range(128) 

這是一個Python特定的錯誤,但什麼讓我困惑的是,我當我運行使用終端程序不會收到此錯誤。我只有在使用php的system函數並從php調用程序時纔會收到此消息。這個問題背後的原因是什麼?

這裏是一個示例代碼:

PHP代碼調用Python程序:

system("python somefile.py $search") // where $search is the variable coming from an input 

Python代碼:

encoding = "iso-8859-9" 
l = "some string here with latin characters" 
print unicode("<div class='line'>%s</div>" % l, encoding) 
# when I run this code from terminal it works perfect and I receive no ??? marks 
# when I run this code from php, I receive the error above 
+0

這可能是一個環境變量。 –

回答

2

PrintFails wiki

When Python finds its output attached to a terminal, it sets the sys.stdout.encoding attribute to the terminal's encoding. The print statement's handler will automatically encode unicode arguments into str output.

這就是爲什麼你的程序在從終端呼叫時起作用。

When Python does not detect the desired character set of the output, it sets sys.stdout.encoding to None, and print will invoke the "ascii" codec.

這就是爲什麼你的程序失敗時,從PHP調用。 爲了使它在從php中調用時能夠工作,您需要明確什麼編碼print應該使用。例如,要作出明確要在utf-8編碼(當沒有連接到終端)的輸出:

ENCODING = sys.stdout.encoding if sys.stdout.encoding else 'utf-8' 
print unicode("<div class='line'>%s</div>" % l, encoding).encode(ENCODING) 

或者,你可以設置PYTHONIOENCODING environment variable。 然後你的代碼應該沒有變化(從終端和從PHP調用時)工作。

+0

你的答案解決了我的問題。謝謝 – Shaokan

2

當運行在終端的Python腳本,你的終端很可能以UTF8編碼(特別是如果您使用的是Linux或Mac)。

當您設置l變量"some string with latin characters",該字符串將被編碼的默認編碼,如果您使用的是終端l將是UTF8和腳本不會崩潰。

小提示:如果您有LATIN1編碼的字符串,你希望它在Unicode的,你可以這樣做:

variable.decode('latin1')