美文网首页
python---字符编码问题

python---字符编码问题

作者: 只爱榛果拿铁 | 来源:发表于2017-04-01 18:09 被阅读0次

问题

最近在用python 2.7写代码的时候,遇到一个老生常谈的小坑----- ** 字符编码 **

import MySQLdb
conn = MySQLdb.connect(host=..., user=..., passwd=..., db=..., charset='utf8', port=...)  //此处已设置charset为utf8

从数据库获取到的数据是:value = '\u6295\u8d44。。。。。' ** 注意:前面没有u **
然后在django后端views.py中,

from django.http import JsonResponse

用JsonResponse(value)返回数据,前端进行渲染,结果在页面上不显示返回结果。

排查过程

  • 打开chrome的console调试,发现报错500--Internal Server Error。。。
  • 查看log发现出现两种报错:'utf8' codec can't decode bytes in position 3-4: invalid continuation byte 和 'ascii' codec can't decode byte 0xe4 in position 0
  • views.py的开头,已经指定了utf-8显示:
# -*- encoding: utf-8 -*-
importsyswufazhengquejiexi
reload(sys)
sys.setdefaultencoding('utf-8')

调试(工具为ipython)

查看变量value的类型,可见value并不是unicode类型,而是str类型

分析

首先我们看下在python中,unicode 和 utf-8/gb2312/ascii 的区别 (参照百度百科)

  • unicode :在python中是一个类,函数unicode(str,"utf8"),将utf8编码(或其他编码)的字符串str转换为unicode类的对象。它表示一个变量的类型,可以用isinstance(value, unicode)来查看value变量是否为unicode格式的字符。
  • ascii :是一种字符集,包括大小写的英文字母、数字、控制字符等,翻译为美国信息互换标准代码,是美国国家标准学会(ANSI)制定的英文编码。
  • gb2312:国标码,是对 ASCII 的中文扩展
  • utf-8:是一种针对unicode的可变长度字符编码,它是在互联网上使用最广的一种unicode的实现方式,是为传输而设计的编码,并使编码无国界,这样就可以显示全世界上所有文化的字符了
  • gb2312和utf-8都是按照unicode规定的方式,用不同的编码排列方式,将字符与二进制的01进行对应的表。

然后我们研究下python中的encode和decode函数:

unicode_1 = u'中文'
str_1 = unicode_1.encode('gb2312')

将unicode对象unicode_1用gb2312编码,得到str类型变量str_1,结果见图:


unicode_2 = str_1.decode('gb2312')

用gb2312编码对字符串str_gb进行解码,得到unicode类型对象,结果见图:

decode()和encode()关系如图:


解决办法

现在回到我们的问题中,查看了一下mysql数据库,发现里面存储的数据确实是utf-8格式,因此用网上搜到的方法

value = value.decode('gb2312').encode('utf-8')

来修改代码,前端仍然不显示。这里是因为数据库里存储的并非gb2312格式的数据,所以decode是没用的。
再查,发现产生 ‘XXX' codec can't decode bytes in position XX 这种错误信息的真正原因,竟然是decode过程中遇到了非法字符,因此无法正确解码(参照:blog.csdn.net/cnmilan/article/details/9264643)。
而在做decode时,加上ignore参数,则会忽略非法字符:

value = value.decode('utf-8', 'ignore').encode('utf-8')

至此,问题得到解决。

总结

一定要真正理解unicode和utf-8的区别,还有要梳理清楚decode()和encode()的关系,排查出问题的真正原因,而不是随便在网上搜索模糊的答案,一来未必能真正解决问题,二来永远不会进步!

相关文章

  • python---字符编码问题

    问题 最近在用python 2.7写代码的时候,遇到一个老生常谈的小坑----- ** 字符编码 ** 从数据库获...

  • 编码

    参考:字符编码常识及问题解析深入分析 Java 中的中文编码问题 关于字符编码,你所需要知道的 编码是什么? 编码...

  • python 字符 编码 简述

    字符编码问题很简单,当你可以区分以下几种概念之后: 字节编码与字符编码 字节串与字符串 文件编码、IDE编码、其他...

  • 字符编码问题

  • 字符编码问题

    计算机只能处理数字, 但是如果要处理文本,就要将文本转化为数字才能处理。最早的计算机采用8位作为一个字节,也就是说...

  • 字符编码问题

    原文地址:http://www.cnblogs.com/hy928302776/archive/2013/04/2...

  • 字符编码问题

    之前在十个经验点总结中提到了utf-8,之前也特地去了解了一些,大多是懵懵懂懂,所以这里又重新上网搜了各种资料,看...

  • 数据结构与算法-练习2

    一、字符编码问题 题目: 字符串编码,编码规则为: k[encoded_string],表示其中方括号内部的 en...

  • Java基础day21笔记:字符编码|“联通”|练习

    2019/7/11 17:04 三刷留念 07-字符编码 既然讲到了字符编码,我们就讲一讲编码解码的问题...

  • 黑客攻防技术宝典之编码方案

    URL编码 只要用于对扩展ASCII字符集中任何有问题的字符进行编码,使其可通过HTTP安全传输。任何URL编码的...

网友评论

      本文标题:python---字符编码问题

      本文链接:https://www.haomeiwen.com/subject/nxxwottx.html