2013-07-02 15 views
7

私は、いくつかの文字列をUTF-8エンコーディングで書き込むPythonスクリプトを持っています。私のスクリプトでは、主に文字列にキャストするのにstr()関数を使用しています。Python UnicodeとLinuxの理解

私は標準のLinux Red Hat x86_64端末であるPython端末を使用していません。 utf8の文字を出力するように端末を設定しました。

私はこれを実行した場合:

#python myscript.py 
this is unicode string: カラダーズ ソフィー 

をしかし、私はそれを行う場合:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 253-254: ordinal not in range(128) 

なぜそれがある:

#python myscript.py > output 

を私は典型的なエラーが発生しましたか?

+0

、あなたが言った、「UTF-8エンコーディングといくつかの文字列は、」どのように文字列がUTF-8でエンコードされたことを確認することができ、あなたは何をしましたか? –

+0

@ venus.w大変申し訳ございませんが、お手伝いできません。私は、UTF-8でエンコードされているDBとCSVの両方から文字列を読み込んでいますが、エンコーディングは実際にはUTF-8であると仮定しています(プリントすると日本語の文字を正しく読み込むことができます)。実際には他の文字セットでエンコードされており、日本語文字も使用できます。私はあなたに文字列のエンコーディングを教えて、それを変更することができるPython関数があると信じています。 – Cesc

答えて

15

の端末は、文字セットを持っている、とPythonはその文字セットが何であるかを知っているので、それは自動的に端末があなたのケースをUTF-8に、使用していますバイトエンコーディングにあなたのUnicode文字列をデコードします。

しかし、あなたがリダイレクトするとき、あなたは、端末を使用しなくなりました。あなたは今Unixパイプを使っています。そのUnixパイプには文字セットがなく、Pythonは現在どのエンコーディングを望んでいるのかわからないので、デフォルトの文字セットに戻ります。 "Python-3.x"で質問をマークしましたが、printの構文はPython 2です。実際にはPython 2を使用していると思われます。は一般的に'ascii'で、あなたの場合は間違いありません。もちろん、日本語の文字をASCIIでエンコードすることはできないので、エラーが発生します。 Pythonの2を使用して

あなたの最善の策は、それを印刷する前に、UTF-8の文字列を符号化することです。その後、リダイレクトが機能し、結果のファイルはUTF-8になります。つまり、あなたの端末が何か他のものであれば動作しませんが、sys.stdout.encodingから端末エンコーディングを取得し、それを使用できます(Python 2でリダイレクトする場合はNoneになります)。

Python 3では、print mystringprint(mystring)に変更する必要がある点を除いて、コードはそのまま動作するはずです。あなたの質問に

+0

はい、それはPython 2です、私はちょうど確認、申し訳ありません。あなたが正しいとすれば、私はそうです:mystring.encode( 'utf-8')を印刷すると、リダイレクトに問題はありません。正確な説明をありがとう。 – Cesc

+3

あなたは同様に[ 'PYTHONIOENCODING'環境変数(http://docs.python.org/2/using/cmdline.html#envvar-PYTHONIOENCODING)でパイプを使用する場合、異なる符号化を使用するのPythonを強制することができます。 –

+0

あなたは 'それを印刷する前にutf-8で文字列をデコードする'と言っていますが、 'それを印刷する前にunicodeをutf8でエンコードしてください'(mystring.encode( 'utf-8'))。 – AlbertFerras

2

それは端末に出力した場合、Pythonは文字セットを選択する$LANGの値を調べることができます。リダイレクトすると、すべてのベットはオフになります。