为什么 Python 2 的 raw_input 输出 unicode 字符串?

Why does Python 2's raw_input output unicode strings?

我在 Codecademy's Python lesson

上尝试了以下操作
hobbies = []

# Add your code below!
for i in range(3):
    Hobby = str(raw_input("Enter a hobby:"))
    hobbies.append(Hobby)

print hobbies

有了这个,它工作正常,但如果我改为尝试

Hobby = raw_input("Enter a hobby:")

我得到 [u'Hobby1', u'Hobby2', u'Hobby3']。额外的 u 是从哪里来的?

'u' 表示它是一个 unicode。您也可以指定 raw_input().encode('utf8') 转换为字符串。

已编辑: 我检查了 python 2.7 它 returns 字节字符串不是 unicode 字符串。所以问题是这里的其他东西。

已编辑: raw_input() returns unicode 如果 sys.stdin.encoding 是 unicode。

在codeacademy python环境中,sys.stdin.encoding和sys.stdout.decoding都是none,默认编码方案是ascii。

Python 只有在无法从环境中找到合适的编码方案时才会使用此默认编码。

您可以在将字符串附加到您的列表之前对其进行编码:

hobbies = []

# Add your code below!
for i in range(3):
    Hobby = raw_input("Enter a hobby:")
    hobbies.append(Hobby.encode('utf-8')

print hobbies

问题的主题行可能有点误导:Python 2 的 raw_input() 通常 return 是一个字节字符串,而不是 Unicode 字符串。

但是,它 可以 return 一个 Unicode 字符串,如果它或 sys.stdin 已经被更改或替换(由应用程序,或作为Python).

的替代实现

因此,我相信@ByteCommander 的评论是正确的:

Maybe this has something to do with the console it's running in?

Codecademy 使用的 Python 表面上是 2.7,但 (a) 它是通过使用 Emscripten 将 Python 解释器编译为 JavaScript 和 (b)在浏览器中是 运行;所以在这些因素之间,Codecademy 很可能注入了一些字符串编码和解码,这在普通 CPython.

中是不存在的

注意:我自己没有使用过 Codecademy,也不了解其内部工作原理。

Where are the extra us coming from?

  • raw_input() return您环境中的 Unicode 字符串
  • repr() 如果您打印列表的每个项目(转换为字符串)
  • Unicode 字符串的文本表示 (repr()) 与 Python 中的 Unicode 文字相同:u'abc'.

这就是为什么 print [raw_input()] 可能会产生:[u'abc'].

您在第一个代码示例中看不到 u'',因为 str(unicode_string) 调用了 unicode_string.encode(sys.getdefaultencoding()) 的等价物,即,它将 Unicode 字符串转换为字节串——不要这样做,除非你是认真的。

可以raw_input()returnunicode吗?

Yes:

#!/usr/bin/env python2
"""Demonstrate that raw_input() can return Unicode."""
import sys

class UnicodeFile:
    def readline(self, n=-1):
        return u'\N{SNOWMAN}'

sys.stdin = UnicodeFile()
s = raw_input()
print type(s)
print s

输出:

<type 'unicode'>
☃

实际示例是 win-unicode-console 包,它可以替代 raw_input() 以支持在 Windows 上的控制台代码页范围之外输入 Unicode 字符。相关:这里是 why sys.stdout should be replaced.

可能raw_input()returnunicode?

是的。

raw_input() is documented to return a string:

The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that.

String in Python 2 是字节串或 Unicode 字符串:isinstance(s, basestring).

CPython of raw_input() 显式支持 Unicode 字符串:builtin_raw_input() can call PyFile_GetLine() and PyFile_GetLine() considers bytestrings and Unicode strings to be strings—it raises TypeError("object.readline() returned non-string") otherwise.