从python2,python3编码问题引伸出的通用编码原理解释

今天使用python2编码时遇到这样一条异常UnicodeDecodeError: ‘ascii’ code can’t decode byte 0xef

发现是编码问题,但是平常在python3中几乎没有遇到过,所以特意查了资料,原来python3和python2对于字符串的理解不一样,在python3中,字符串默认unicode编码

一.解释python2和python3文本处理方式

在Python3当中,文本字符串类型(使用Unicode数据存储)被命名为 str , 字节字符串类型被命名为 bytes 。一般情况下,实例化一个字符串会得到一个 str 对象 :

如果你想得到bytes,那就在文本之前加上前缀 b , 或者 encode 一下。

所以,很显然,str 对象有一个encode方法,bytes 对象有一个decode方法。

在Python3中的 str 对象在Python2中叫做 unicode , bytes 对象在Python2中叫做 str

在python2中使用中文字符串的方式是在页首声明# *--coding:utf-8--*

 

二.常用编码方式

顺便在网上查了一下字符集和编码方式的文档,发现很多人都解释的难以理解,所以这里尝试说清楚一下。这里不解析字符集和编码方式,统称为编码方式。

不论什么编码,在计算机中统一是按照二进制字节形式存储,一个字节有8位

1.ASCII码,总共有128个,用1个字节的低7位来表示

2.ISO-8859-1,128个字符表示明显不够用,所以ISO组织又制订了新的标准来扩展ASCII码,它们是ISO-8859-1到ISO-8859-15,其中ISO-8859-1涵盖了大部分西欧编码,所以用的最多。ISO-8859-1也是单字节编码,总共表示256个字符,发现字符变成?时,一般是使用了ISO-8859-1编码,规定不认识范围内的使用3f表示的就是?

3.GB2312,双字节编码,范围为A1-F7,其中A1-A9是符号区,包含682个符号,B0-F7是汉字区,包含6763个汉字,汉字使用两个字节表示

4.GBK,用于扩展GB2312,编码范围8140~FEFE,总共有23940个码位,使用GB2312编码的汉字可以用GBK来解码

5.UTF-16,所有字符都是用两个字节,两个字节为16bit,所以叫UTF-16,但是浪费空间.(同unicode)

6.UTF-8,每个编码区域有不同的字码长度,最长为三个字节,编码规则如下:

(1)如果一个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间。0之后的所有部分(7个bit)代表在Unicode中的序号。
(2)如果一个字节以110开头,那么代表当前字符为双字节字符,占用2个字节的空间。110之后的所有部分(7个bit)代表在Unicode中的序号。且第二个字节以10开头
(3)如果一个字节以1110开头,那么代表当前字符为三字节字符,占用2个字节的空间。110之后的所有部分(7个bit)代表在Unicode中的序号。且第二、第三个字节以10开头
(4)如果一个字节以10开头,那么代表当前字节为多字节字符的第二个字节。10之后的所有部分(6个bit)代表在Unicode中的序号

具体每个字节的特征可见下表,其中x代表序号部分,把各个字节中的所有x部分拼接在一起就组成了在Unicode字库中的序号

Byte 1 Byte 2 Byte3
0xxx xxxx    
110x xxxx 10xx xxxx  
1110 xxxx 10xx xxxx 10xx xxxx

我们分别看三个从一个字节到三个字节的UTF-8编码例子:

实际字符 在Unicode字库序号的十六进制 在Unicode字库序号的二进制 UTF-8编码后的二进制 UTF-8编码后的十六进制
$ 0024 010 0100 0010 0100 24
¢ 00A2 000 1010 0010 1100 0010 1010 0010 C2 A2
20AC 0010 0000 1010 1100 1110 0010 1000 0010 1010 1100 E2 82 AC

细心的读者不难从以上的简单介绍中得出以下规律:

  • 3个字节的UTF-8十六进制编码一定是以E开头的
  • 2个字节的UTF-8十六进制编码一定是以CD开头的
  • 1个字节的UTF-8十六进制编码一定是以比8小的数字开头的

三.常见问题处理之Emoji

所谓Emoji就是一种在Unicode位于\u1F601\u1F64F区段的字符。这个显然超过了目前常用的UTF-8字符集的编码范围\u0000\uFFFF。Emoji表情随着IOS的普及和微信的支持越来越常见。下面就是几个常见的Emoji:

那么Emoji字符表情会对我们平时的开发运维带来什么影响呢?最常见的问题就在于将他存入MySQL数据库的时候。一般来说MySQL数据库的默认字符集都会配置成UTF-8(三字节),而utf8mb4在5.5以后才被支持,也很少会有DBA主动将系统默认字符集改成utf8mb4。那么问题就来了,当我们把一个需要4字节UTF-8编码才能表示的字符存入数据库的时候就会报错:ERROR 1366: Incorrect string value: ‘\xF0\x9D\x8C\x86‘ for column 。 如果认真阅读了上面的解释,那么这个报错也就不难看懂了。我们试图将一串Bytes插入到一列中,而这串Bytes的第一个字节是\xF0意味着这是一个四字节的UTF-8编码。但是当MySQL表和列字符集配置为UTF-8的时候是无法存储这样的字符的,所以报了错。

【附】手持两把锟斤拷, 口中疾呼烫烫烫。 脚踏千朵屯屯屯, 笑看万物锘锘锘。

时间: 2024-10-10 05:30:10

从python2,python3编码问题引伸出的通用编码原理解释的相关文章

python2和python3编码

python2编码 unicode:unicode 你好 u'\u4f60\u597d' | | | | encode('utf8')| |decode('utf8') encode('gbk')| |decode('gbk') | |   | | utf8    gbk编码后的str '\xe4\xbd\xa0\xe5\xa5\xbd'     编码后的gbk u'\u6d63\u72b2\u30bd' # str: bytes >>> s = '你好 world' >>&

day07 python2与python3 编码

详细文章: http://www.cnblogs.com/yuanchenqi/articles/5956943.html http://www.diveintopython3.net/strings.html 需知: 1.在python2默认编码是ASCII, python3里默认是unicode 2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-

python2和python3编码解码详解

今天让我们一起彻底揭开py编码的真相,包括py2和py3.有同学可能问:以后py3是大势所趋,还有必要了解py2那令人头疼的编码吗?答案是太有必要啦.py2在生产中还是中流砥柱. 什么是编码? 基本概念很简单.首先,我们从一段信息即消息说起,消息以人类可以理解.易懂的表示存在.我打算将这种表示称为"明文"(plain text).对于说英语的人,纸张上打印的或屏幕上显示的英文单词都算作明文. 其次,我们需要能将明文表示的消息转成另外某种表示,我们还需要能将编码文本转回成明文.从明文到编

[转载]Python3编码问题详解

原文:Python3的编码问题 Python3 最重要的一项改进之一就是解决了 Python2 中字符串与字符编码遗留下来的这个大坑.Python 编码为什么那么蛋疼?已经介绍过 Python2 字符串设计上的一些缺陷: 使用 ASCII 码作为默认编码方式,对中文处理很不友好. 把字符串的牵强地分为 unicode 和 str 两种类型,误导开发者 在Python3中,从sys中可以看出使用的默认编码 >>> import sys >>> sys.getdefault

python3编码问题

继续收集python3编码问题相关资料 资料来源  鹏程的新浪博客(转载)http://blog.sina.com.cn/s/blog_6d7cf9e50102vo90.html  这篇鹏程老师写的关于python3的编码的博客写的特别的清楚,直接就摘入下来.供自己作为参考. 1.从字节说起: 一个字节包括八个比特位,每个比特位表示0或1,一个字节即可表示从00000000到11111111共2^8=256个数字.一个ASCII编码使用一个字节(除去字节的最高位作为作奇偶校验位),ASCII编码

Ubuntu16.04 下python2 | python3

在终端分别输入python,python2,python3 python和python2默认都是python2 python3才是python3 Ubuntu下是默认没有pip的,需要自己手动安装 sudo apt install python-pip #安装python2的pip sudo apt install python3-pip # 安装python3的pip pip list #查看python2下的pip安装包 pip3 list #查看python3下pip安装包 更换pip源

windows和linux下 Python2,Python3 的环境及安装

目录 windows和linux下 Python2,Python3 的环境及安装 window下安装 一. 手动安装 二. pip安装 linux下 安装 更新Python 笔者有话 windows和linux下 Python2,Python3 的环境及安装 window下安装 1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\python27 3.配置环境变量 [右键计算机]-->[属性]-->[高级系统设置]-->[高级

python2 python3区别(续)

1.除法 Python2 Python3 int/int → int int/int → float python2下整数除以整数返回整数类型,python3下整数除以整数返回浮点数类型 当某些语句假定变量为整数类型时,上面的区别会造成python3下的运行时错误. 建议兼容写法: 建议新写python2脚本时加入from __future__ import division, 这样Python2的脚本就会与python3行为一致,也返回浮点数. 必须使用整数的地方建议使用类型转换, int()

Python2.7编码问题:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position...解决方法

解决方法: 在Python程序最前面加上以下语句: import sys reload(sys) sys.setdefaultencoding('utf-8') Python2.7编码问题:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position...解决方法 原文地址:https://www.cnblogs.com/sea-stream/p/10836056.html