unicode_literals是用来做什么的?

55
我在Python中使用__future__.unicode_literals时遇到了一个奇怪的问题。如果不导入unicode_literals,则可以得到正确的输出:
# encoding: utf-8
# from __future__ import unicode_literals
name = 'helló wörld from example'
print name

但是当我添加了unicode_literals导入:

# encoding: utf-8
from __future__ import unicode_literals
name = 'helló wörld from example'
print name

我收到了这个错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 4: ordinal not in range(128)

unicode_literals 是否将每个字符串编码为 utf-8? 如何覆盖此错误?


另请参阅:Python、Unicode 和 Windows 控制台,了解相关的、特定于 Windows 的问题。


13
这个导入语句只会对Python 2产生影响;它可以让Python 2像Python 3一样处理字符串,从而使你的代码能够在不同版本的Python中运行。 - Martijn Pieters
2
问题出在你的终端上,它无法显示非 ASCII 字符。 - roippi
1
由于您使用print作为一个语句,所以您一定是在使用Python 2版本;我已经移除了让我误解的python-3.x标签。 - Martijn Pieters
@roippi:不,它完全能够显示已经编码为UTF-8的字节。它没有向Python“通信”它正在使用UTF-8。 - Martijn Pieters
是的,我本可以更好地表达那句话。 - roippi
2个回答

63

您的终端或控制台无法让Python知道它支持UTF-8编码。

没有 from __future__ import unicode_literals 这一行,你正在构建一个包含UTF-8编码字节的字节串。如果你使用字符串,则你正在构建一个 unicode 字符串。

print 必须要对这两个值进行不同的处理;字节串会不经改变地写入到 sys.stdout 中。unicode 字符串首先被编码成字节,Python 会根据 sys.stdout.encoding 来进行编码。如果您的系统没有正确告诉 Python 它所支持的编解码器,那么默认使用 ASCII 编码。

您的系统未能告诉 Python 使用什么编解码器;因此,sys.stdout.encoding 被设置为 ASCII 编码,并且编码 unicode 值以进行打印失败。

您可以在打印时手动将其编码为 UTF-8 来验证:

# encoding: utf-8
from __future__ import unicode_literals
name = 'helló wörld from example'
print name.encode('utf8')

如果没有使用from __future__导入语句,您也可以通过创建Unicode字面量来重现该问题:

# encoding: utf-8
name = u'helló wörld from example'
print name

其中u'..'也是一个Unicode字面量。

如果没有提供你的环境细节,很难说解决方案是什么;这在很大程度上取决于所使用的操作系统和控制台或终端。


3

截至2023年(及以后)的简短回答

你的代码很可能支持Python >= 3,对吧?

因此,你可以删除这个语句。

__future__.unicode_literals旨在实现Python 2 <-> 3的向前/向后兼容性(请阅读文档)。

由于Python 2已经不再得到官方支持,因此没有理由保留这个向前兼容代码。(当然,除非你关心长期支持发行版的用户)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接