分享

(ok)Python3编码解码问题汇总

 hdzgx 2020-01-08

一、解码问题: ‘utf-8’ codec can’t decode byte 0xa8 in position xx: invalid start byte

【问题描述】:

笔者通过Python3从数据库(HBase)中取数据的时候,报错如下:
在这里插入图片描述
报错信息显示,在内置函数转换获取的数据(字节数组)为字符串str时,UTF-8编码方案无法对字节\xa8进行解码,该字节0xa8在当前字节数组的索引是21(从0开始计数)。

【问题分析】:

在解决这个问题之前,我们首先来回顾一下Python3中编码解码之间的转换关系如下(欲全面了解编码和解码问题详情点击此处):
在这里插入图片描述
可见,当数据含有中文其他特殊字符时,Unicode码被编码成非UTF-8和非ASCII码(如GBK码)后,再用UTF-8解码就会出错。因为,它们根本就不是一套编码方案。

本例中,我无法解码的数据在本地的显示是:

Ecole Polytechnique Fédérale de Lausanne (EPFL)

在数据库中的显示是:
在这里插入图片描述
我们都知道Python中,UTF-8码会将Unicode码中的每个非ASCII字符编码成2~3个字节(中文是3个字节,这里的é是两个字节),格式是\x##

所以,我们可以推断出,在数据被传输或存储前,Unicode码所表示的str,被转换成了非UTF-8编码。这自然在编辑或获取数据时,无法用UTF-8码解码成Unicode,上例中的第一个非ASCII字节\xA8即为报错信息索引为21中的0xa8

至此,我们完全理解了为什么会出错,和具体在哪个位置出的错

【解决思路】:
  1. 在str数据被传输或存储前,保证其为Unicode码,再对其进行UTF-8编码(.encode('utf-8'))。
  2. 在str数据被编辑或获取前,对其进行UTF-8解码(.decode('utf-8'))为Unicode码。
  3. 对于需要和数据库交互的情况,往往譬如insert()get()等方法都会内置字符串str字节数组bytes之间的转换函数,为防止其不被转换成GBK等其他编码,所以只要在传入数据前保证其为Unicode码即可。
本例中我的解决方案:

保证上传的字段valueUnicode码,即成功。

def function(...,value=str(value).encode('utf-8').decode('utf-8'),...)

utf-8编码后的数据在数据库中的显示,该字节可被utf-8解码为Unicode码:
在这里插入图片描述

二、编码问题:‘gbk’ codec can’t encode character ‘\uxxxx’ in position xxxxx: illegal multibyte sequence

【问题描述】:笔者在Windows系统下尝试将数据库中数据读取出来,并写入到本地.txt文件中报错。

报错代码如下:

    with open('C:\\Users\\Administrator\\xxx\\content.txt', 'w') as f:
        f.write(str_data)

读取亦然:

    with open('C:\\Users\\Administrator\\xxx\\content.txt', 'r') as f:
        str_data = f.read()

意思是在索引为26088的'\u0141'Unicode码表示的字节无法被GBK编码方案编码。在这里插入图片描述
在这里插入图片描述

【问题分析】:

Windows系统默认是GBK编码,所以在单独设置编码方案的时候,系统会自动默认为GBK编码,对于含有非中文的字符就无法编码。

【解决方案】:

不论数据中是否含有中文等非ASCII字符,直接编码成UTF-8即可。

    with open('C:\\Users\\Administrator\\xxx\\content.txt', 'w', encoding='utf-8') as f:
        f.write(str_data)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多