多次编码(使用相同的编码格式)字符串是否有任何损害? (在Python中)

时间:2010-12-11 21:03:01

标签: python unicode encoding utf-8

在python中使用相同的编码格式多次编码字符串有什么危害吗? (即UTF-8)?

我有一个函数,它使用另一个函数从文档中获取字符串,然后序列化字符串。目前,第二个函数的唯一用户(从文档中获取字符串的用户)是第一个函数。

将来可能会发生变化,有人可能决定在另一个序列化(或类似)函数中使用它,而不首先将其结果编码为UTF-8。我想知道总是从它返回一个UTF-8编码的字符串是否安全(此字符串也将通过序列化函数重新执行.encode())。我的测试表明这不是问题,但是,我想我会问。

谢谢!

4 个答案:

答案 0 :(得分:5)

你不能多次编码,它不起作用。

>>> s = u"ä".encode('latin1')
>>> s = s.encode('latin1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

看,你得到“ascii编解码器无法解码”。字符串上的编码方法的作用是首先将解码字符串转换为Unicode,然后使用给定的编码再次对其进行编码。它将使用系统编码对其进行解码,默认情况下为ascii。

这种行为是出乎意料的,并且在Python 3中顺便说一句,顺便说一句,其中字节没有编码方法,字符串没有解码方法。

所以你根本无法对它进行多次编码,当然这是因为编码一个编码的字符串根本没有任何意义。编码是从Unicode转换为二进制表示,您无法进一步编码二进制表示。

答案 1 :(得分:1)

除非字符串是纯粹的ascii,否则它会造成伤害(如果它是纯粹的ascii,你不需要担心utf-8):

>>> a
u'a \xd7 b'
>>> a.encode("utf-8")
'a \xc3\x97 b'
>>> a.encode("utf-8").encode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in range(128)

将字节序列和文本视为两个不同的东西是一种好习惯。在Python 3中,它们是不同的东西:字节对象具有decode()方法,字符串(unicode)对象具有encode()方法。

答案 2 :(得分:1)

一般情况下,您只应在encode个对象上调用unicode,并且只能在decode个对象上调用string

encode将Unicode对象编码为给定的编码(存储为字符串)。 decode将给定的编码解码回Unicode对象。

2.x中string.encodeunicode.decode的存在应被视为历史文物。

答案 3 :(得分:0)

好吧,如果你有一个UTF-8编码文本的字节流,你把它们解释为用其他东西编码的字符串然后重新编码为UTF-8,那么你就有问题。

如果你再次将它读作UTF-8(因为你不能将字节视为没有编码的文本),那么你就有了Unicode,当再次写成UTF-8时,它看起来和以前一样。

请注意不要过多地使用编码。一个常见的错误是将UTF-8编码的文本解释为拉丁语1,从而将Fööbär转换为Fööbär,然后当然不会再次更改。

请注意 text (您关心的实际内容)与编码文本之间的区别,编码文本只是一堆字节以及如何将它们转换为文本的知识再次。如果将后者视为前者,就会出现问题。如果你正确地从一个表示转换到另一个表示,那很好。