2015-10-16 62 views
1

我从数据库查询中读取一个值,该值生成一个unicode字符串。由于此处无关的原因,数据输入人员将字符串值输入到数据库中,如“Assessor's Parcel”(注意“反向”撇号)。我正在编写刚刚通过选定数据库记录并打印出文本的代码。我使用.format()操作将变量中的文本插入到打印输出中。众所周知,传递unicode字符串时.format失败。因此,减少这种对难题,我提出下面的例子:带有打印和格式的unicode字符串输出不一致()

>>> a = u"Assessor’s Parcel" 
>>> a 
u'Assessor\u2019s Parcel' 
>>> print a 
Assessor’s Parcel 
>>> "{0}".format(a) 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 8: ordinal not in range(128) 
>>> 

以上线是从的PythonWin的“交互窗口”(PythonWin的2.7.5(默认情况下,22:43 2013年5月15日,: 36)在win32上[MSC v.1500 32位(Intel)]。)

为什么'print a'产生的输出不仅仅是'a'?为什么呢,如果其中任何一个能产生合理的输出,.format()不能?

如果我确定我不能输出unicode文本(对于某些尚未知的原因),并且我会满足包含“\ u”语法的输出,那么是否真的必须包装我的所有字符串在某些代码(方法或其他)中执行转换的数据库值的输出?

+0

必要链接http://bit.ly/unipain – Daenyth

回答

2

只是use unicode! (请注意,你的错误是该HOWTO的第一个例子)

这个问题不是格式化,而是因为你试图把一个unicode对象放入一个字节串,所以它试图对它进行编码使用ascii的默认编码)。相反,如果你试图把它格式化成Unicode字符集的文字就没有问题..

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

它也不会是一个问题,如果你把一个字节串到字节串。

>>> '{}'.format(a.encode('utf8')) 
'Assessor\xe2\x80\x99s Parcel' 
>>> print '{}'.format(a.encode('utf8')) 
Assessor’s Parcel 
>>> 

但是,这使得以后输出到另一个(不同的)编码更加困难。

0

简单'a'要求类的方法中的“最原始”的值的形式。打印通过str()转换值的驱动器。格式表达式通过另一个不同的转换发送它,一个当前以ASCII工作。

0

下面是我的几次尝试正确打印。 print a.encode('utf-8')似乎是一个解决方案:

>>> a = u"Assessor’s Parcel" 
>>> a 
u'Assessor\u2019s Parcel' 

>>> print a 
Assessor’s Parcel 

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

>>> a.encode('utf-8') 
'Assessor\xe2\x80\x99s Parcel' 

>>> print a..encode('utf-8') 
    File "<stdin>", line 1 
    print a..encode('utf-8') 
      ^
SyntaxError: invalid syntax 

>>> print a.encode('utf-8') 
Assessor’s Parcel 

>>> print a.encode('utf-8') 
Assessor’s Parcel 

>>> print a..encode('utf-8') 
    File "<stdin>", line 1 

    print a..encode('utf-8') 
      ^
SyntaxError: invalid syntax 

>>> a.encode('utf-8') 
'Assessor\xe2\x80\x99s Parcel' 

>>> print a.encode('utf-8') 
Assessor’s Parcel 
0

在交互式shell中,'a'确实打印出一个表示。您可以使用print repr(a)

print a将打印str(a)输出到标准输出。 print将始终编码输出,无论输出的编码是什么。所以print a类似于sys.stdout.write(a.encode(sys.stdout.encoding) + "\n")

请注意u"string""string"之间的区别。首先是一个Unicode字符串 - 一个Unicode代码点的序列,而后者是一个二进制字符串 - 一个字节序列。Python 3在两者之间做出了更加严格的区分(我实际上更喜欢Python 3,因为它更挑剔,因此更好地告诉我我做错了什么)

"{0}".format(a),"{0}"是一个二进制字符串。您尝试在该二进制字符串中格式化非ASCII字符的unicode字符串。这失败了,因为你需要告诉Python如何从Unicode转换为二进制字符串。所以你可以这样做:"{0}".format(a.encode('utf-8'))

但是,您可能不想要一个格式化的二进制字符串,而是一个格式化的Unicode字符串。在这种情况下,您可以编写:u"{0}".format(a)