2011-09-09 5 views
3

私はPythonプログラムがうまく動作しています。いくつかのウェブサイトに接続し、必要な情報を出力します。すべてのウェブサイトがutf-8でエンコードされているわけではないので、ヘッダーから文字セットを要求し、unicode(string, encoding)メソッドを使用してデコードしています(これを行う適切な方法かどうかはわかりませんが、私がPythonプログラムを実行すると、私はno ???マークとそれは正常に動作します。私はPHPのsystem機能を使用してプログラムを実行するときしかし、私はこのエラーが表示されます。phpシステム、python、utf-8

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

これは、Python固有のエラーですが、何を私に混乱することは、私は、端末を使用してプログラムを実行したときに、私はこのエラーを受信しないということです。私はPHPのsystem関数を使用し、phpからプログラムを呼び出すときにのみこれを受け取ります。この問題の原因は何でしょうか?ここで

はサンプルコードです:Pythonプログラムを呼び出す

PHPコード:

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

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で使用するエンコードを明示する必要があります。

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を設定できます。たとえば、あなたが(端末に接続されていない場合)utf-8でエンコードされた出力を望んでいることを明示的にします。 そして、あなたのコードは変更なしで(端末からもphpから呼び出されても)動作します。

+0

あなたの答えは私の問題を解決しました。ありがとう – Shaokan

2

あなたのターミナルでPythonスクリプトを実行して、あなたの端末UTF8でコード化されている可能性があります(特にLinuxやMacを使用している場合)。

変数を"some string with latin characters"に設定すると、その文字列がデフォルトのエンコードにエンコードされます。端末を使用している場合は、lはUTF8になり、スクリプトはクラッシュしません。

少しヒント:あなたはlatin1の中でエンコードされた文字列を持っていて、あなたが行うことができますUnicodeでそれをしたい場合:PrintFails wikiから

variable.decode('latin1')