Skip to main content
 首页 » 编程设计

Python2.7 打印 unicode 字符串仍然出现 UnicodeEncodeError : 'ascii' codec can't encode character . .. 序号不在范围内(128)

2025年05月04日18TianFang

一个简单的打印函数

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 中以某种方式失败。

我在这里做错了什么?

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

请您参考如下方法:

不同的终端(和 GUI)允许不同的编码。我手边没有最新的 ipython,但它显然能够处理字符串中的非 ASCII 0xe7 字符 ('ç')。然而,您的普通控制台正在使用 'ascii' 编码(在异常中以名称提及),它不能显示任何大于 0x7f 的字节。

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

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

errors may be given to set a different error handling scheme. The default for errors is 'strict', meaning that encoding errors raise a UnicodeError. Other possible values are 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' and any other name registered via codecs.register_error(), see section 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“Unicode HOWTO”和 Ned Batchelder 的“Pragmatic Unicode, or, How Do I Stop the Pain?”,也可作为 36 分钟的 video from PyCon US 2012 获得.

编辑:...或者,正如您似乎已经发现的那样,您的终端可以很好地显示 Unicode,但您的默认编码仍然设置为 'ascii' ,这比它需要的更具限制性。