52

すべてのロケールが UTF-8 である最近の Linux システムを実行しています。

LANG=de_DE.UTF-8
LANGUAGE=
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
...
LC_IDENTIFICATION="de_DE.UTF-8"
LC_ALL=

ここで、UTF-8 でエンコードされたコンテンツをコンソールに書き込みたいと思います。

現在、Python は FS エンコーディングに UTF-8 を使用していますが、デフォルトのエンコーディングには ASCII を使用しています :-(

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> sys.getfilesystemencoding()
'UTF-8'

PYTHONIOENCODINGこれを行うための最良の(クリーンな)方法は、環境変数を設定することだと思いました。しかし、Pythonはそれを無視しているようです。少なくとも私のシステムでは、 envvarasciiを設定した後でも、デフォルトのエンコーディングとして取得し続けます。

# tried this in ~/.bashrc and ~/.profile (also sourced them)
# and on the commandline before running python
export PYTHONIOENCODING=UTF-8

スクリプトの開始時に次のようにすると、機能します。

>>> import sys
>>> reload(sys)  # to enable `setdefaultencoding` again
<module 'sys' (built-in)>
>>> sys.setdefaultencoding("UTF-8")
>>> sys.getdefaultencoding()
'UTF-8'

しかし、そのアプローチは不潔に思えます。それで、これを達成するための良い方法は何ですか?

回避策

デフォルトのエンコーディングを変更する代わりに-これは良い考えではありません(メシリアックの回答を参照)-私は次sys.stdoutのようにラップしStreamWriterます:

sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)

それを処理する小さなユーティリティ関数については、この要点を参照してください。

4

5 に答える 5

29

これを達成することはお勧めできません。

Fedoraはデフォルトとしてシステムロケールを使用することを提案しましたが、明らかにこれは他のものを壊します。

メーリングリストのディスカッションからの引用は次のとおりです。

Pythonでサポートされているデフォルトのエンコーディングは次のとおりです。

 Python 2.x:ASCII
 Python 3.x:UTF-8

これらを変更すると、あなたは自分自身になり、奇妙なことが起こります
起こり始めます。デフォルトのエンコーディングは影響するだけではありません
Pythonと外の世界の間の翻訳だけでなく
8ビット文字列とUnicode間のすべての内部変換。

パンゴモジュールで起こっていることのようなハック(
でサイトモジュールをリロードすることにより、デフォルトのエンコーディングは「utf-8」になります
sys.setdefaultencoding()APIを取り戻すための順序は
Unicode以来、まったく間違っており、深刻な問題を引き起こします
オブジェクトは、デフォルトのエンコードされた表現をキャッシュします。

ロケールベースのデフォルトエンコーディングの使用を有効にしないでください。

達成したいのは、のエンコーディングを取得することだけです。
stdoutとstdinがパイプ用に正しく設定されている場合は、
代わりに、それらの.encoding属性を変更してください(のみ)。

- 
マーク・アンドレ・レンバーグ
eGenix.com
于 2012-07-31T14:54:56.557 に答える
24

これは私がそれを行う方法です:

#!/usr/bin/python2.7 -S

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

バンラインの に注意-Sしてください。これは、モジュールを自動的にインポートしないように Python に指示しsiteます。モジュールはデフォルトのsiteエンコーディングを設定するものであり、メソッドを削除するため、再度設定することはできません。しかし、すでに設定されているものを尊重します。

于 2012-07-31T14:35:58.983 に答える