在python中使用相同的编码格式多次编码字符串有什么危害吗? (即UTF-8)?
我有一个函数,它使用另一个函数从文档中获取字符串,然后序列化字符串。目前,第二个函数的唯一用户(从文档中获取字符串的用户)是第一个函数。
将来可能会发生变化,有人可能决定在另一个序列化(或类似)函数中使用它,而不首先将其结果编码为UTF-8。我想知道总是从它返回一个UTF-8编码的字符串是否安全(此字符串也将通过序列化函数重新执行.encode())。我的测试表明这不是问题,但是,我想我会问。
谢谢!
答案 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.encode
和unicode.decode
的存在应被视为历史文物。
答案 3 :(得分:0)
好吧,如果你有一个UTF-8编码文本的字节流,你把它们解释为用其他东西编码的字符串然后重新编码为UTF-8,那么你就有问题。
如果你再次将它读作UTF-8(因为你不能将字节视为没有编码的文本),那么你就有了Unicode,当再次写成UTF-8时,它看起来和以前一样。
请注意不要过多地使用编码。一个常见的错误是将UTF-8编码的文本解释为拉丁语1,从而将Fööbär
转换为Fööbär
,然后当然不会再次更改。
请注意 text (您关心的实际内容)与编码文本之间的区别,编码文本只是一堆字节以及如何将它们转换为文本的知识再次。如果将后者视为前者,就会出现问题。如果你正确地从一个表示转换到另一个表示,那很好。