しばらくの間、print
を使用できないと仮定します(したがって、自動エンコーディング検出の利点を享受できます)。つまり、sys.stdout
が残ります。ただし、sys.stdout
は非常に馬鹿げているので 意味のあるエンコーディングは行いません 。
ここで、Python wikiページ PrintFails を読み、次のコードを試してみます。
$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout);
ただし、これも機能しません(少なくともMacでは)。理由がわかりすぎます:
>>> import locale
>>> locale.getpreferredencoding()
'mac-roman'
>>> sys.stdout.encoding
'UTF-8'
(UTF-8は端末が理解できるものです)。
したがって、上記のコードを次のように変更します。
$ python -c 'import sys, codecs, locale; print str(sys.stdout.encoding); \
sys.stdout = codecs.getwriter(sys.stdout.encoding)(sys.stdout);
これで、Unicode文字列がsys.stdout
に適切に送信されるため、端末に適切に出力されます(sys.stdout
は端末に接続されています)。
これはsys.stdout
でUnicode文字列を書く正しい方法ですか、それとも何か他のことをする必要がありますか?
[〜#〜] edit [〜#〜]:時々-たとえば、出力をless
--sys.stdout.encoding
にパイプするときNone
になります。この場合、上記のコードは失敗します。
印刷ができない理由は私にはわかりません。しかし、そうだとすれば、そうです、アプローチは私には正しく見えます。
export PYTHONIOENCODING=utf-8
仕事をしますが、それをpython自体に設定することはできません...
私たちにできることは、が設定されていないかどうかを確認し、スクリプトを呼び出す前に設定するようにユーザーに指示することです。
if __name__ == '__main__':
if (sys.stdout.encoding is None):
print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
exit(1)
最良のアイデアは、端末に直接接続されているかどうかを確認することです。もしそうなら、端末のエンコーディングを使用してください。それ以外の場合は、システム優先エンコーディングを使用してください。
if sys.stdout.isatty():
default_encoding = sys.stdout.encoding
else:
default_encoding = locale.getpreferredencoding()
また、ユーザーが必要なエンコーディングを常に指定できるようにすることも非常に重要です。通常、私はそれをコマンドラインオプション(-e ENCODING
など)にし、optparse
モジュールで解析します。
もう1つの良い点は、notsys.stdout
を自動エンコーダーで上書きすることです。エンコーダーを作成して使用しますが、sys.stdout
はそのままにしておきます。エンコードされたバイト文字列をsys.stdout
に直接書き込むサードパーティライブラリをインポートできます。
オプションの環境変数「PYTHONIOENCODING」があり、これを希望のデフォルトエンコーディングに設定できます。これは、すべてのPythonと一貫性のある方法で、ユーザーが希望するエンコーディングを取得する1つの方法です。 Pythonマニュアル ここ に埋もれています。
これは私が私のアプリケーションで行っていることです:
sys.stdout.write(s.encode('utf-8'))
これは、argvからUTF-8名を読み取るための正反対の修正です。
for file in sys.argv[1:]:
file = file.decode('utf-8')
これは非常に醜い(IMHO)ので、UTF-8を使用する必要があります。これはLinux/Macでは標準ですが、Windowsでは標準ではありません...とにかく私には機能します:)