Python 中 unicode() 和 encode() 函数的使用

Posted

技术标签:

【中文标题】Python 中 unicode() 和 encode() 函数的使用【英文标题】:Usage of unicode() and encode() functions in Python 【发布时间】:2012-05-04 12:08:09 【问题描述】:

我在编码 path 变量并将其插入到 SQLite 数据库时遇到问题。我试图用 encode("utf-8") 函数解决它,但没有帮助。然后我使用了 unicode() 函数,它给了我类型 unicode

print type(path)                  # <type 'unicode'>
path = path.replace("one", "two") # <type 'str'>
path = path.encode("utf-8")       # <type 'str'> strange
path = unicode(path)              # <type 'unicode'>

最后我获得了 unicode 类型,但是当 path 变量的类型为 str

sqlite3.ProgrammingError: 你不能使用 8 位字节串,除非 您使用可以解释 8 位字节串的 text_factory(例如 text_factory = str)。强烈建议您改为 将您的应用程序切换为 Unicode 字符串。

你能帮我解决这个错误并解释encode("utf-8")unicode()函数的正确用法吗?我经常和它打架。

编辑:

这个 execute() 语句引发了错误:

cur.execute("update docs set path = :fullFilePath where path = :path", locals())

我忘记更改遇到同样问题的 fullFilePath 变量的编码,但我现在很困惑。我应该只使用 unicode() 还是 encode("utf-8") 还是两者都使用?

我不能用

fullFilePath = unicode(fullFilePath.encode("utf-8"))

因为它引发了这个错误:

UnicodeDecodeError: 'ascii' 编解码器无法解码位置的字节 0xc5 32:序数不在范围内(128)

Python 版本是 2.7.2

【问题讨论】:

引发错误的代码在哪里? 您的确切问题已经得到解答:[***.com/questions/2392732/… [1]: ***.com/questions/2392732/… @newtover 我编辑了问题。 您是否将两个使用的变量都转换为unicode 学习 Python 3 handles 文本和数据确实帮助我理解了一切。然后很容易将知识应用到 Python 2。 【参考方案1】:

str 是以字节为单位的文本表示,unicode 是以字符为单位的文本表示。

您将文本从字节解码为 un​​icode,然后使用某种编码将 unicode 编码为字节。

即:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc'

UPD Sep 2020:答案是在 Python 2 主要使用时编写的。在 Python 3 中,str 重命名为 bytesunicode 重命名为 str

>>> b'abc'.decode('utf-8') # bytes to str
'abc'
>>> 'abc'.encode('utf-8'). # str to bytes
b'abc'

【讨论】:

非常好的答案,直截了当。我要补充一点,unicode 讲的是字母或符号,或者更笼统地说:runesstr 表示某种编码的字节字符串,你必须decode(显然是正确的encoding) 来获取特定的符文 Python 3.8 >> 'str' object has no attribute 'decode' 您有将 unicode 更改为 str 的文档吗?我找不到 @cikatomo 这是 Python 3 的关键变化之一:docs.python.org/3.0/whatsnew/…【参考方案2】:

您错误地使用了encode("utf-8")。 Python 字节字符串(str 类型)有编码,Unicode 没有。您可以使用uni.encode(encoding) 将Unicode 字符串转换为Python 字节字符串,也可以使用s.decode(encoding)(或等效的unicode(s, encoding))将字节字符串转换为Unicode 字符串。

如果fullFilePathpath 当前是str 类型,您应该弄清楚它们是如何编码的。例如,如果当前编码是 utf-8,您可以使用:

path = path.decode('utf-8')
fullFilePath = fullFilePath.decode('utf-8')

如果这不能解决问题,实际问题可能是您在 execute() 调用中没有使用 Unicode 字符串,请尝试将其更改为以下内容:

cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())

【讨论】:

这条语句fullFilePath = fullFilePath.decode("utf-8") 仍然会引发错误UnicodeEncodeError: 'ascii' codec can't encode characters in position 32-34: ordinal not in range(128)。 fullFilePath 是类型 str 和取自 db 表的 text 列的字符串的组合,应该是 utf-8 编码。 根据this,但它可以是UTF-8、UTF-16BE或UTF-16LE。我能以某种方式找到它吗? @xralf,如果您正在组合不同的 str 对象,您可能正在混合编码。你能显示print repr(fullFilePath)的结果吗? 我只能在调用 decode() 之前显示它。有问题的字符是 \u0161 和 \u0165。 @xralf - 所以它已经是 unicode 了?尝试将执行调用更改为 unicode:cur.execute(u"update docs set path = :fullFilePath where path = :path", locals())【参考方案3】:

确保在从 shell 运行脚本之前设置好你的区域设置,例如

$ locale -a | grep "^en_.\+UTF-8"
en_GB.UTF-8
en_US.UTF-8
$ export LC_ALL=en_GB.UTF-8
$ export LANG=en_GB.UTF-8

文档:man localeman setlocale

【讨论】:

以上是关于Python 中 unicode() 和 encode() 函数的使用的主要内容,如果未能解决你的问题,请参考以下文章

解决python中遇到的乱码问题

python中unicode 和 str相互转化

了解python中bytes,str和unicode的区别

Python 中 unicode() 和 encode() 函数的使用

python中unicode的坑

在 Python 2 和 Python 3 中有效的原始 unicode 文字?