<p>这主要是因为python2中的字符串不是文本字符串,而是<strong>字节字符串。你知道吗</p>
<p>我假设您在REPL环境(Python控制台)中。当您在控制台中计算某个内容时,会得到它的<em>打印表示形式</em>,这与在表达式上调用<code>print repr()</code>相同:</p>
<pre><code>l = ['ñ']
l[0] # should output '\xc3\xb1'
print repr(l[0]) # should output the same
</code></pre>
<p>这是因为您的控制台处于UTF-8模式(如果您得到不同的<code>ñ</code>表示,这是因为您的控制台使用其他一些文本表示),所以当您按<code>ñ</code>时,实际上输入了两个字节<code>0xc3</code>和<code>0xb1</code>。你知道吗</p>
<p><a href="https://docs.python.org/2/library/functions.html#repr" rel="nofollow">^{<cd6>}</a>是一个始终返回字符串的Python方法。对于基元类型,此字符串是重建作为参数传递的值的有效源。在本例中,它返回一个包含字节序列的字符串,该字符串重新创建另一个<code>ñ</code>编码为UTF-8的字符串。要看到这一点:</p>
<pre><code>repr(l[0]) # should print a string within a string: "'\\xc3\\xb1'"
</code></pre>
<p>因此,当您打印它时(这与在控制台中进行求值相同),您将得到相同的字符串,但没有正确替换外引号和转义字符。即:</p>
<pre><code>print repr(l[0]) # should output '\xc3\xb1'
</code></pre>
<p>但是,当您打印值时,即:<code>print l[0]</code>,然后将这两个字节发送到控制台。由于控制台处于UTF-8模式,它对序列进行解码并将其转换为一个字符:<code>ñ</code>。所以:</p>
<pre><code>print l[0] # should output ñ
</code></pre>
<p>如果要存储文本字符串,必须在字符串前面使用修饰符<code>u</code>。这样:</p>
<pre><code>text = u'ñ'
</code></pre>
<p>现在,在计算文本时,您将看到<a href="http://www.fileformat.info/info/unicode/char/f1/index.htm" rel="nofollow">its Unicode codepoint</a>:</p>
<pre><code>text # should output u'\xf1'
</code></pre>
<p>打印时应重新创建<code>ñ</code>字形:</p>
<pre><code>print text # should output `ñ`
</code></pre>
<p>如果要将<code>text</code>转换为字节字符串表示,则需要编码方案(如UTF-8):</p>
<pre><code>text.encode('utf-8') == l[0] # should output True
</code></pre>
<p>同样,如果您想要<code>l[0]</code>的Unicode表示,则需要对这些字节进行解码:</p>
<pre><code>l[0].decode('utf-8') == text # should output True
</code></pre>
<p>注意,在python3中,默认字符串实际上是Unicode字符串,您需要在文字表示法前面加上<code>b</code>来生成字节字符串。你知道吗</p>