<p>首先,<code>ISO-8859-1</code>不是有效的编码声明。你想要<code>iso-8859-1</code>。如果您看一下<a href="http://docs.python.org/2/library/codecs.html" rel="nofollow">the docs</a>,您可以将其称为<code>latin_1</code>、<code>iso-8859-1</code>、<code>iso8859-1</code>、<code>8859</code>、<code>cp819</code>、<code>latin</code>、<code>latin1</code>、或{<cd10>},但不能叫{<cd1>}。在</p>
<p>看起来<code>codecs.lookup</code>向后弯曲以接受错误的输入,包括执行不区分大小写的查找。如果跟踪<a href="http://hg.python.org/cpython/file/2.7/Lib/codecs.py" rel="nofollow">^{<cd12>}</a>到{a3}到<a href="http://hg.python.org/cpython/file/2.7/Python/codecs.c" rel="nofollow">^{<cd15>}</a>,则可以看到以下注释:</p>
<pre><code>/* Convert the encoding to a normalized Python string: all
characters are converted to lower case, spaces and hyphens are
replaced with underscores. */
</code></pre>
<p>但是源文件解码并没有经过相同的编解码器查找过程。因为它发生在编译时而不是运行时,所以没有理由这么做。(无论如何,他会说“虽然医生说这是错误的,但它似乎起作用了……那么为什么它不能完全起作用?”一开始就有点傻。)</p>
<p>为了演示,如果我创建两个拉丁语-1文件:</p>
<p>在坏代码.py公司名称:</p>
^{pr2}$
<p>在好代码.py公司名称:</p>
<pre><code># -*- coding: iso-8859-1 -*-
print u"Vérifier l'affichage de cette chaîne"
</code></pre>
<p>第一个失败了,第二个成功了。在</p>
<p>现在,为什么它在控制台时“工作”,而在管道传输时引发异常?在</p>
<p>好吧,当您打印到Windows控制台或unixtty时,Python有一些代码可以尝试猜测要使用的正确编码。(我不知道在Windows上会发生什么;据我所知,它甚至可能使用UTF-16输出。)当您不打印到控制台/TTY时,它不能这样做,所以您必须显式地指定编码。在</p>
<p>您可以通过查看<code>sys.stdout.isatty()</code>、<code>sys.stdout.encoding</code>、和{<cd18>}来了解发生了什么。以下是我在Mac电脑上看到的不同情况:</p>
<ul>
<li>Python2,无重定向:<code>True, UTF-8, ascii, Vérifier</code></li>
<li>Python3,无重定向:<code>True, UTF-8, utf-8, Vérifier</code></li>
<li>Python2,重定向:<code>False, None, ascii, UnicodeEncodeError</code></li>
<li>Python3,重定向:<code>False, UTF-8, utf-8, Vérifier</code></li>
</ul>
<p>如果<code>isatty()</code>,<code>encoding</code>将是TTY的适当编码;否则,<code>encoding</code>将是默认值,在2.x中是<code>None</code>(意思是<code>ascii</code>),并且(我想-我必须检查代码)基于3.x中的<code>getdefaultencoding()</code>的内容。这意味着如果您试图打印Unicode,而<code>stdout</code>不是2.x中的TTY,它将尝试将其编码为<code>ascii</code>,<code>strict</code>,如果您有非ASCII字符,则将失败。在</p>
<p>如果您不知何故知道要使用哪个编解码器,则可以通过检查<code>isatty()</code>并对该编解码器进行编码(如果愿意,甚至可以选择<code>ascii</code>,<code>ignore</code>而不是{<cd31>})来手动处理,而不是尝试打印Unicode。(如果你知道你想要什么样的编解码器,即使在3.x版本中也可以这么做,如果你想生成,比如说,Windows-1252文件,那么默认为UTF-8也没有太大帮助…)</p>
<p>这里的区别实际上与拉丁语-1无关。试试这个:</p>
<p>在无代码.py公司名称:</p>
<pre><code>print u"V\xe9rifier l'affichage de cette cha\xeene"
print u"V\u00e9rifier l'affichage de cette cha\u00eene"
</code></pre>
<p>对于我的Mac终端,我将Unicode字符串编码为UTF-8,并(显然)将Windows-1252编码到windowscmd窗口,但重定向到文件时出现异常。在</p>