Python:在Unicode转义字符串上使用.format()

165
我正在使用Python 2.6.5版本。我的代码需要使用“大于或等于”符号。这里是代码:
>>> s = u'\u2265'
>>> print s
>>>>>> print "{0}".format(s)
Traceback (most recent call last):
     File "<input>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265'
  in position 0: ordinal not in range(128)`  

为什么我会收到这个错误?有没有正确的方法来做这件事?我需要使用.format()函数。

3个回答

251

只需将第二个字符串也设置为Unicode字符串即可。

>>> s = u'\u2265'
>>> print s
≥
>>> print "{0}".format(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)
>>> print u"{0}".format(s)
≥
>>> 

42
如果您希望所有字面值都是Unicode(就像Python 3中那样),请在源文件开头加上from __future__ import unicode_literals - Philipp
1
如果你习惯使用"%s" % u"\u2265"这种格式化方式,那么这个例子可能会让你感到困惑。因为使用"{}".format(u"\u2265")的方式会抛出一个异常。 - Hylidan
2
多么简单的事情啊。。我找到了这一点启示之前,头痛了好久。 - Iosu S.

73

unicode需要使用unicode格式的字符串。

>>> print u'{0}'.format(s)
≥

9
关于为什么会发生这种情况,我有更多信息。
>>> s = u'\u2265'
>>> print s

print自动使用系统编码(通常是UTF-8)来工作,因此可以正常工作。您可以通过执行import sys; print sys.stdout.encoding来检查。

>>> print "{0}".format(s)

失败是由于format尝试匹配调用它的类型的编码(我无法找到关于这一点的文档,但这是我注意到的行为)。由于Python 2中的字符串字面量是以ASCII编码的字节字符串,因此format试图将s编码为ASCII,然后导致该异常。例如:

>>> s = u'\u2265'
>>> s.encode('ascii')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)

所以这些方法之所以有效,基本上就是因为这个原因:
>>> s = u'\u2265'
>>> print u'{}'.format(s)
≥
>>> print '{}'.format(s.encode('utf-8'))
≥

源字符集由编码声明定义;如果源文件中没有给出编码声明,则为ASCII。详情请参阅:https://docs.python.org/2/reference/lexical_analysis.html#string-literals

1
哦,我发现这篇文章对于理解Python中的Unicode和计算机系统中的文本表示非常有帮助:https://nedbatchelder.com/text/unipain.html - lps

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