Python中的Unicode字符串
我需要把一个包含度数符号(°)的字符串写入文件。
这个字符串存储在一个变量里,按照预期,当我尝试用 f.write(myVariable.encode('utf-8'))
写入时,我遇到了 UnicodeDecodeError 的错误。
如果我像这样写这个字符串到文件:
x = u'aaa°°bbb'
f.write(encode(x))
这样是可以的,但我不能在代码里直接写 x = u'aaa°°bbb'
,因为 'aaa°°bbb'
是从数据库里来的,它存储在一个变量中。如果我尝试 newVar = unicode(myVariable)
,我又会遇到 UnicodeDecodeError
的错误。
我需要把 myVariable 转换成 'u' 的格式……我该怎么做呢?
5 个回答
如果 myVariable
是一个来自外部来源(比如数据库)的字符串,你首先需要弄清楚这个字符串是什么类型。
因为你似乎在使用 python2,所以主要有两种可能性:myVariable
要么是一个 unicode 字符串对象,要么是一个 bytes 字符串对象。unicode 字符串是指已经被 解码 成文本字符的字符串,而 bytes 字符串则是已经被 编码 过的字符串(使用像 'utf-8' 或 'latin-1' 这样的编码)。
从你问题中的示例代码来看,myVariable
是一个 bytes 字符串对象。
你遇到第一个 UnicodeDecodeError
的原因是因为你试图对一个字节字符串进行 重新编码。为了做到这一点,python 首先需要将 myVariable
解码成一个 unicode 字符串对象,然后才能应用新的编码。默认情况下,python 在自动解码时会假设使用 "ascii" 编码,但由于 myVariable
包含了超出 ascii 范围(0-128)的字节,因此会发生错误。
当你尝试将 myVariable
传递给 unicode
函数时,也会出现同样的情况。除非你明确指定编码,否则 python 仍然会假设使用 "ascii",这时你会看到同样的 UnicodeDecodeError
。
现在,如果你要将 myVariable
写入文件,如果它是一个 bytes 字符串对象,解决方案非常简单:什么都不用做!直接将 myVariable
写入文件即可:
f = open(path, 'wb')
f.write(myVariable)
f.close()
但是,当你再次读取文件时,你 需要 知道 myVariable
的原始编码,以便将其解码为 unicode:
f = open(path)
myVariable = f.read().decode('utf-8')
f.close()
如果你修改了 myVariable
并想再次写入文件,你必须记住这次它是一个 unicode 字符串,因此你需要先对它进行编码:
f = open(path, 'wb')
f.write(myVariable.encode('utf-8'))
f.close()
根据你的 myVariable
是 Unicode 格式还是字节格式(在 Python 2 和 Python 3 中的叫法不同),你需要决定如何进行转换。
如果 newVar = unicode(myVariable)
这个操作失败了,那你很可能是在字节格式(在 Python 2 中叫 str()
)。所以,你要么需要让你的数据库使用 Unicode 和你沟通,要么就得知道它的编码方式,然后按照这个方式进行解码。
在从数据库中取出数据后,使用你数据库所用的编码方式来解码它。
s.decode('latin1')
当然,如果数据在数据库里一开始就编码错了,那你就得想办法进行补救。
s.encode('latin1').decode('utf8')