如何检查是否已成功编码utf-8

时间:2014-10-06 05:26:52

标签: python

给定一个字符串

u ='abc'

哪种语法是编码成utf8的正确语法?

u.encode('utf-8')

u.encode('utf8')

我怎么知道我已经在utr-8中编码了?

2 个答案:

答案 0 :(得分:3)

首先,如果您正在讨论Python 2或Python 3,则需要进行区分,因为unicode处理是两个版本之间最大的差异之一。

Python 2

  • unicode类型包含文字字符
  • str包含8位字节的序列,有时表示某些未指定编码的文本
  • s.decode(encoding)获取一个序列字节,并在给定字节使用的编码后构建一个文本字符串。它从strunicode,例如"Citt\xe0".decode("iso8859-1")将为您提供文本“Città”(意大利语为城市),"Citt\xc3\xa0".decode("utf-8")也会出现同样的情况。可以省略编码,在这种情况下,含义是“使用默认编码”。
  • u.encode(encoding)接受一个文本字符串,并在给定的编码中构建表示它的字节序列,从而颠倒decode的处理。它从unicodestr。如上所述,编码可以省略。

使用Python处理unicode时的部分困惑是语言试图过于聪明并自动完成。

例如,您也可以在encode对象上调用str,其含义是“编码使用默认编码时解码这些字节的文本,最终使用指定的编码或默认值编码如果没有指定“。

同样,您也可以在decode对象上调用unicode,这意味着“在使用默认编码时解码来自此文本的字节,最终使用指定的编码”。

例如,如果我写

u"Citt\u00e0".decode("utf-8")

Python给出错误:

  

UnicodeEncodeError:'ascii'编解码器无法对字符u'\ xe0'进行编码                       位置3:序数不在范围内(128)

注意:错误是关于编码失败,而我要求解码。原因是我要求解码文本(废话,因为它已经“解码”......它的文本),Python决定首先使用“ascii”编码对其进行编码,但失败了。 IMO要好得多,就是不要在unicode对象上有decode而在字符串对象上没有encode:错误信息会更清楚。

更令人困惑的是,Python 2 str用于未编码的字节,但它也用于文本的所有地方,例如字符串文字是str个对象。

Python 3

要解决一些问题,Python 3做了一些关键的更改

  • str用于文本并包含unicode字符,字符串文字是unicode文本
  • unicode类型不再存在
  • bytes类型用于8位字节序列,可能代表某些未指定编码的文本

例如在Python 3中

'Città'.encode('iso8859-1') → b'Citt\xe0'
'Città'.encode('utf-8')     → b'Citt\xc3\xa0'

您也无法在文本字符串上调用decode,也无法在字节序列上调用encode

故障

有时将文本编码为字节可能会失败,因为指定的编码无法处理所有的unicode。例如iso8859-1无法处理中文。可以通过几种方式处理这些错误,例如引发异常(默认),或者替换无法用其他内容编码的字符。

然而,编码utf-8能够编码任何unicode字符,因此编码到utf-8永远不会失败。 因此,询问如何正确地将utf-8中的编码文本正确完成是没有意义的,因为它始终发生(对于utf-8)。

此外,解码可能会失败,因为字节序列在指定的编码中可能没有意义。例如,字节序列0x43 0x69 0x74 0x74 0xE0不能解释为utf-8,因为如果没有正确的前缀,字节0xE0就不会出现。

有类似iso8859-1的编码,但解码不会失败,因为任何字节0..255都有作为字符的含义。大多数“本地编码”属于这种类型......它们将所有256个可能的8位值映射到某个字符,但只覆盖了一小部分unicode字符。

使用iso8859-1进行解码绝不会引发错误(任何字节序列都有效),但当然如果使用其他编码的字节,它可以为您提供无意义的文本。

答案 1 :(得分:0)

第一个解决方案:

isinstance(u, unicode)

第二个解决方案:

try:
    u.decode('utf-8')
    print "string is UTF-8, length %d bytes" % len(string)
except UnicodeError:
    print "string is not UTF-8"