Python2.7打印unicode字符串仍然得到UnicodeEncodeError:'ascii'编解码器不能编码字符...序号不在范围内(128)

时间:2017-01-10 05:34:01

标签: python python-2.7 unicode python-unicode

简单的打印功能

def TODO(message):
    print(type(message))
    print(u'\n~*~ TODO ~*~ \n %s\n     ~*~\n' % message)

这样称呼

TODO(u'api servisleri için input check decorator gerekiyor')

导致此错误

<type 'unicode'>                                                                                 
Traceback (most recent call last):                                                               
  File "/srv/www/proj/__init__.py", line 38, in <module>                                      
    TODO(u'api servisleri için input check decorator gerekiyor')                                 
  File "/srv/www/proj/helpers/utils.py", line 33, in TODO                                     
    print(u'\n~*~ TODO ~*~ \n %s\n     ~*~\n' % message)                                         
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 32: ordinal not in range(128)

但它适用于ipython控制台

In [10]: TODO(u'api servisleri için input check decorator gerekiyor')
<type 'unicode'>

~*~ TODO ~*~ 
 api servisleri için input check decorator gerekiyor
     ~*~

这适用于python 2.7.12,但在某种程度上以2.7.9失败。

我在这里做错了什么?

编辑:函数在烧瓶应用程序中调用时失败,在python控制台中工作。

3 个答案:

答案 0 :(得分:0)

不同的终端(和GUI)允许不同的编码。我没有最近的ipython,但它显然能够处理字符串中的非ASCII 0xe7字符('ç')。但是,您的普通控制台使用的是'ascii'编码(例外情况中提到的名称),它不能显示大于0x7f的任何字节。

如果要将非ASCII字符串打印到ASCII控制台,则必须决定如何处理它无法显示的字符。 str.encode方法提供了几种选择:

  

str.encode([encoding[, errors]])

     可以给出

errors来设置不同的错误处理方案。   errors的默认值为'strict',表示编码错误会引发UnicodeError。   其他可能的值包括'ignore''replace''xmlcharrefreplace''backslashreplace'以及通过codecs.register_error()注册的任何其他名称,请参阅Codec Base Classes部分。

这是一个使用字符串中的四个备用错误处理程序中的每一个的示例(没有TODO添加的额外修饰):

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from __future__ import print_function

uni = u'api servisleri için input check decorator gerekiyor'
handlers = ['ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace']
for handler in handlers:
    print(handler + ':')
    print(uni.encode('ascii', handler))
    print()

输出:

ignore:
api servisleri iin input check decorator gerekiyor

replace:
api servisleri i?in input check decorator gerekiyor

xmlcharrefreplace:
api servisleri i&#231;in input check decorator gerekiyor

backslashreplace:
api servisleri i\xe7in input check decorator gerekiyor

这些输出中哪一项与您想要的最接近,供您决定。

有关详细信息,请参阅Python 2&#34; Unicode HOWTO&#34;和Ned Batchelder&#34; Pragmatic Unicode, or, How Do I Stop the Pain?&#34;也可以作为36分钟video from PyCon US 2012

编辑:...或者,您似乎已经发现,您的终端可以正常显示Unicode,但您的默认编码仍然设置为'ascii',这是更严格的比它需要的那样。

答案 1 :(得分:-1)

  

\ XE7

代表小'ç'的utf-8字符之一。 Python 2.7.9可能用ASCII编码。您可以在任何代表Python 2.7.9行为的Python版本中运行以下代码。

import sys; 
# -*- coding: utf-8 -*-

def TODO(message):
    print(type(message))
    print(u'\n~*~ TODO ~*~ \n %s\n     ~*~\n' % message)

message = u'api servisleri için input check decorator gerekiyor'
encodedMessage = message.encode('ascii')

print(sys.stdout.encoding)
TODO(encodedMessage)

它将抛出异常

  

Traceback(最近一次调用最后一次):文件“test.py”,第9行,in          encodedMessage = message.encode('ascii')UnicodeEncodeError:'ascii'编解码器无法编码位置16的字符'\ xe7':ordinal   不在范围内(128)

因此,问题与解释器的编码规则有关。您可以自己编码或忽略。

希望它会有用

答案 2 :(得分:-1)

显然,print函数与print语句略有不同。

https://docs.python.org/2.7/library/functions.html#print

All non-keyword arguments are converted to strings like 
str() does and written to the stream, separated by sep 
and followed by end. 

简单地说,编码unicode字符串解决了它

msg = u'\n~*~ TODO ~*~ \n %s\n     ~*~\n' % message
print(msg.encode("utf-8"))

但是,不确定为什么它适用于2.7.12,也许是一个语言环境?