まず、ISO-8859-1
有効なコーディング宣言ではありません。あなたがしたいiso-8859-1
。ドキュメントを見ると、これlatin_1
をiso-8859-1
, iso8859-1
, 8859
, cp819
, latin
, latin1
, またはと呼ぶことができますが、 とL1
は言えませんISO-8859-1
。
codecs.lookup
大文字と小文字を区別しない検索を行うなど、不適切な入力を受け入れるために後方に曲がっているように見えます。codecs.lookup
までたどる_codecs.lookup
と_PyCodec_Lookup
、次のコメントが表示されます。
/* Convert the encoding to a normalized Python string: all
characters are converted to lower case, spaces and hyphens are
replaced with underscores. */
ただし、ソース ファイルのデコードは、同じコーデック ルックアップ プロセスを経由しません。実行時ではなくコンパイル時に発生するため、そうする理由はありません。(とにかく、「ドキュメントが間違っていると言っているのに、うまくいくように見える…では、なぜうまくいかないのですか?」と言うのは、そもそもばかげています。)
たとえば、2 つの Latin-1 ファイルを作成すると、次のようになります。
悪いコード.py:
# -*- coding: ISO-8859-1 -*-
print u"Vérifier l'affichage de cette chaîne"
グッドコード.py:
# -*- coding: iso-8859-1 -*-
print u"Vérifier l'affichage de cette chaîne"
1 つ目は失敗し、2 つ目は成功します。
さて、なぜそれはコンソールに行くときに「動作」するのに、パイプされると例外が発生するのでしょうか?
Windows コンソールまたは Unix TTY に出力する場合、Python には、使用する正しいエンコーディングを推測するためのコードがいくつかあります。(Windows の裏で何が起こっているのかはわかりません。私が知っている限りでは、UTF-16 出力を使用している可能性さえあります。) コンソール/TTY に印刷していない場合、これを行うことはできません。エンコーディングを明示的に指定する必要があります。
sys.stdout.isatty()
、sys.stdout.encoding
、およびを見ると、何が起こっているかがわかりますsys.getdefaultencoding()
。さまざまなケースで Mac に表示されるのは次のとおりです。
- Python 2、リダイレクトなし:
True, UTF-8, ascii, Vérifier
- Python 3、リダイレクトなし:
True, UTF-8, utf-8, Vérifier
- Python 2、リダイレクト:
False, None, ascii, UnicodeEncodeError
- Python 3、リダイレクト:
False, UTF-8, utf-8, Vérifier
の場合isatty()
、encoding
TTY の適切なエンコーディングになります。それ以外の場合encoding
は、デフォルト値になります。これは、2.x ではNone
(つまり)、(コードを確認する必要があると思います) 3.xascii
に基づくものです。getdefaultencoding()
つまり、 が 2.x で TTY でないときに Unicode を印刷しようとすると、 ,stdout
としてエンコードしようとしますが、非 ASCII 文字があると失敗します。ascii
strict
使用するコーデックがどういうわけかわかっている場合は、Unicode を印刷しようとする代わりに、印刷するたびisatty()
にそのコーデック (または、必要に応じて の代わりに ) をチェックしてエンコードすることascii
によりignore
、手動でこれに対処できます。strict
(必要なコーデックがわかっている場合は、3.x でもこれを行うことができます。たとえば、Windows-1252 ファイルを生成しようとしている場合、UTF-8 をデフォルトに設定してもあまり役に立ちません…)
そこの違いは、実際には Latin-1 とは何の関係もありません。これを試してください:
nocode.py:
print u"V\xe9rifier l'affichage de cette cha\xeene"
print u"V\u00e9rifier l'affichage de cette cha\u00eene"
Mac ターミナルでは UTF-8 にエンコードされた Unicode 文字列を取得し、Windows コマンド ウィンドウでは (明らかに) Windows-1252 にエンコードされますが、例外がファイルにリダイレクトされます。