繁体   English   中英

Python 2.X:为什么我不能正确处理Unicode?

[英]Python 2.X: Why Can't I Properly Handle Unicode?

我用Python 2.X和unicode进行了一段时间的实验。 但是我已经达到了没有意义的地步。

第一个问题:

有些代码会清楚地解释我的意思。 txt变量用于模拟pyqt4转换函数。 它返回一个QString。

# -*- coding: utf-8 -*-
from PyQt4 import QtCore
txt = QtCore.QString(u'può essere / sarà / 日本語')
txtUnicode1 = unicode(txt, errors='replace')
txtUnicode2 = unicode(txt)

当print() - 两个unicode字符串时,我得到:

pu esstre/sar / ???

puòessere/sarà/日本语

当然我可以通过使用QString .__ str __()获得相同的东西,但我的观点是理解,所以为了争论我想知道:

  • 为什么error ='replace'会替换所有编码字符,只有在出现错误时才应该这样做?
  • 使用unicode(QString)将QString变成适合显示的unicode字符串是否有问题?

第二个问题:

我想了解编码/解码。

>>> a = u'può essere / sarà / 日本'
>>> b = a.encode('utf-8')
>>> a
u'pu\xf2 essere / sar\xe0 / \u65e5\u672c'
>>> b
'pu\xc3\xb2 essere / sar\xc3\xa0 / \xe6\x97\xa5\xe6\x9c\xac'
>>> print a
può essere / sarà / 日本
>>> print b
può essere / sarà / 日本
  • 打印是否解码a和b?
  • 编码编码的UTF-8应该完全解码? 我不应该打印编码的字符串吗?
  • 编码和解码的unicode字符串有什么区别?

首先,我建议你阅读Joel Spolesky撰写的优秀文章, 绝对最低限, 每个软件开发人员绝对必须知道Unicode和字符集 它不是关于Python,而是应该帮助您理解正在发生的事情。

在Python 3中,unicode字符串和普通字符串之间的区别变得更加清晰,但在Python 2中也是如此.unicode字符串包含字符串的unicode表示,普通字符串是包含该unicode表示的编码的字节字符串。 unicode类型的文档解释了正在发生的事情。 通过传入errors参数, unicode的作用与它未传递的时间不同,并且它正在尝试解码字符串。 目前还不清楚它试图从哪个编码解码,但它可能认为它是utf-8,当它实际上是utf-16或类似的时候。

print语句将unicode字符串编码为终端正在使用的任何编码。 这可能是ascii,或者它可能是utf-8或其他东西。 print a实际上是在print a.encode('utf-8')

我没有回答你的所有问题,但我链接的文章应该回答大部分问题。 希望这可以帮助!

让我们启动旧的待机,IDLE,看看我们是否可以复制你所看到的内容。

IDLE 1.1.4      
>>> a = u'può essere / sarà / 日本'

Unsupported characters in input
>>> a = u'pu\xf2 essere / sar\xe0 / \u65e5\u672c'
>>> b = a.encode('utf-8')
>>> a
u'pu\xf2 essere / sar\xe0 / \u65e5\u672c'
>>> b
'pu\xc3\xb2 essere / sar\xc3\xa0 / \xe6\x97\xa5\xe6\x9c\xac'
>>> print a
può essere / sarà / 日本
>>> print b
può essere / sarà / 日本

请注意,当我打印b时,我看到了不同的东西。 这是因为我的shell(IDLE)不会将字节序列解释为UTF-8文本,而是使用我的平台字符编码cp1252。

让我们仔细检查一下。

>>> import sys
>>> sys.stdout.encoding
'cp1252'

是的,这就是为什么我的行为与你不同的原因。 因为你的sys.stdout.encoding是UTF-8。 这就是为什么,尽管ab是完全不同的值,它们显示相同; 您的终端将字节解释为UTF-8。

所以,你可能会想,如果我们可以把我们的Unicode字符序列转换a成可以显示在空闲的字节序列

>>> c = a.encode('cp1252') 

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in -toplevel-
    c = a.encode('cp1252') #uses default encoding
  File "C:\Python24\lib\encodings\cp1252.py", line 18, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 20-21: character maps to <undefined>

答案是不; cp1252不支持将中文字符编码为字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM