从Python的角度来看编码与解码
导语:
Python2和Python3中,因为默认字符集的不同而造成的麻烦,简直是程序员的梦魇!要彻底告别这个麻烦,就需要从本质上来理解编码和解码。
为什么要有编码?
对于不会英文的中国人来说,将英文翻译成中文,这个就叫做解码;而将中文翻译成英文,自然就是编码了!
这个道理在计算机中同样适用。
计算机只能识别0和1,任何文字对于计算机来说,就是0和1的排列组合。但是我们人类哪看得懂这种0和1的排列组合!
自然就需要将0和1的文字转换为我们能看得懂的文字,比如中文,英文等。
而这种0和1到文字的映射,就叫做解码;文字到0和1的映射自然就是编码了!
有了映射关系,自然就需要有个类似“表格”的东西,来记录这种映射关系了!这个“表格”就是我们常说的字符集(也叫编码集,简称编码),比如ascii编码,utf-8字符集。
习惯上,我们把人类能看懂的文字叫做字符,对应的计算机能看得懂的文字叫做字符编号(也就是字节流),而字符集就是这种字符和字符编号的映射。
为什么会有乱码?
上面我们说到,字符集有多种,那么问题来了。
比如,在编码时,我采用utf-8字符集进行文字到0和1的映射,但是解码时,又采用gbk的字符集进行0和1到文字的映射,
2种字符集的映射规则是不一样的!结果自然就是乱码!
这就像我买了张三家的锁,却用李四家配的钥匙来开门,能开门就见鬼了!
(其实对于计算机来说,根本没有乱码这一说法!对于特定的字符,0和1的排列组合是唯一不变的,变得是映射后的文字。)
关于文件编码
不知道有没有人有过这样的疑问,CPU一个只能运算0和1的器件,是如何能够处理文本、图片、视频和声音这些资源的?
其实这就要讲到文件编码。
以下文字来自知乎网友的解答:
链接:https://www.zhihu.com/question/27805272/answer/74539468
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
文字: 有若干种标准可以用8~16位二进制数表示一个字符,比如用8位数表示英语字母数字的ASCII,用16位数表示几乎所有语言所有字符的Unicode等。以ASCII为例,这个标准用01000001这个数表示大写的A,于是某个文字处理软件看到这个数字知道这是A,然后向一个字体文件询问字母A长什么样,然后把它画在屏幕上,你就看到了A。 图像: 最简单的格式叫“位图”(BMP),用24位二进制数表示图像中的一个点,这24位数中8位表示这个点有多少红色,8位表示多少绿色,8位表示多少蓝色,三种原色组合起来就可以表示几乎所有的颜色。很多个24位数连在一起,就是很多个点,于是就组成了一幅图像。除此以外还有其他格式以更少的数字表示同样多的图像内容,如JPG、PNG等。 声音: 声音是波,是数学上的连续函数,而计算机无法理解连续函数,所以每秒取样44100次,把1秒的声音变成44100个数字记录下来,这是录音的过程。回放时,把这些数字交给声卡,声卡控制喇叭按照这些数字表示的幅度震动,就发出了声音。同样,除了44100个数字(这是WAV格式)以外还有其他格式以更少的数字表示同样多的声音,如MP3、OGG等。 视频: 既然有了图像和声音的标准,那么每秒钟24~60幅图像再加上1秒钟的声音就组成了1秒钟的视频内容。不过这种做法的数据量异常庞大,所以没人这么干,科学家们发明了各种编码方式以非常非常少(相对于未压缩)的数字表示同样多的视频内容,如H.264等。 各种软件控制CPU按照各种标准理解了多媒体内容后,计算出屏幕上每一个点应该是什么颜色(和位图一样),然后把这些计算结果交给显卡,显卡把这一堆数字表示的颜色画到屏幕上,这叫做一次刷新。一般来说每秒刷新60次,这样你就流畅地看到了你所打开的多媒体内容。
了解了编码和解码的大环境之后,再来看看Python中的编码和解码:
字符串类型
Python2中字符串类型有2种,unicode和str。
其中普通字符串为unicode形式,字节流为str。
>>> s = '中国'
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> u = u'中国'
>>> u
u'\u4e2d\u56fd'
>>> type(s)
<type 'str'>
>>> type(u)
<type 'unicode'>
Python3中字符串类型只有str一种;
另外需要注意的一点就是:python3中str即Unicode,3中的字符串默认都是Unicode形式。
>>> s = '中国'
>>> s
'中国'
>>> type(s)
<class 'str'>
>>> u = u'中国'
>>> u
'中国'
>>> type(u)
<class 'str'>
默认字符集
Python2中默认字符集为ascii,其中默认中文字符集为utf-8。
>>> sys.getdefaultencoding()
'ascii'
Python3中,无论什么文,默认字符集为utf-8。
>>> sys.getdefaultencoding()
'utf-8'
关于编码和字节流
编码的结果为字节流。
Python2,str即是字节流
>>> u.encode('gbk')
'\xd6\xd0\xb9\xfa'
>>> u.encode('utf-8')
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> s = b'中国'
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> type(s)
<type 'str'>
>>> bytes(s)
'\xe4\xb8\xad\xe5\x9b\xbd'
Python3,不能够直接定义中文字节流
>>> s.encode('utf-8')
b'\xe4\xb8\xad\xe5\x9b\xbd'
>>> s = b'中国'
File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
关于解码
解码的结果为str(python3)或者unicode(python2)
Python2
>>> s.decode('utf-8')
u'\u4e2d\u56fd'
>>> u
u'\u4e2d\u56fd'
Python3
>>> a
b'\xe4\xb8\xad\xe5\x9b\xbd'
>>> a.decode()
'中国'
检测
可以通过isinstance()来判断类型
>>> isinstance(a,str)
True
>>> isinstance(b'qq',str)
True
关于错误
1.
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte
出现上述错误的原因在于:
编码时使用的字符集和解码时使用的字符集不一致。
注意:open()方法,在window下默认的字符集为gbk;Linux下默认字符集是utf-8,所以在window下可能需要指定encoding='utf-8'。
本地语言环境:locale.getdefaultlocale()
当前编码集:sys.getdefaultencoding()
Linux下
>>> import locale
>>> locale.getpreferredencoding()
'UTF-8'
window下
'cp936'
936为代码页编号,表示gbk。
65001表示utf-8。
2.
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 4-5: truncated \UXXXXXXXX escape
由于转义字符造成的错误。
如果文件中存在转义字符,比如window下常见的路径名"C:\Users\leo\Desktop"("\U"是转义字符,表示unicode字符),这时就会出现上述错误。
解决方式有2种:
1.在转义字符前加上"\"。
2.在字符串前加上r,表示使用原始字符串。
拓展:
\0x:当输出的数转换为16进制只有1位时,在前面补0,如 0a,其它情况按照实际情况输出。 \x:按照输出数转换为16进制的实际位数输出。 此外,小写x和大写X也有点区别,小写的x输出小写符号的16进制,大写X则输出大写的(主要针对ABCDEF这六位)
从Python的角度来看编码与解码的更多相关文章
- Python中进行Base64编码和解码
Base64编码 广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容 ...
- python中的URL编码和解码
python中的URL编码和解码:test.py # 引入urllib的request模块 import urllib.request url = 'https://www.douban.com/j/ ...
- python学习笔记09-python编码与解码
二进制编码: --->ASCII:只能存英文和拉丁字符 一个字符占一个字节:8位 ------>gb2312:只能存6700多个中文: 1980年发表 ----------->gbk ...
- python中字符串的编码和解码
1. 常用的编码 ASCII:只能表示一些字母,数字和特殊的字符,占一个字节 GBK:国家简体中文字符集和繁体字符集,兼容ASCII,占两个字节 Unicode:能够表示全世界上所有的字符,Unico ...
- python is == 的区别, 编码与解码.深浅拷贝
一. is == 的区别 双等表示的是判断是否相等, 注意. 这个双等比较的是具体的值.而不是内存地址 is 比较的是地址 编码回顾 除了了ASCII码以外, 其他信息不能直接转换 编码和解码的时 ...
- python字符串格式和编码与解码问题
%c 转换成字符(ASCII码值,长度为一的字符串) %r 有线使用repr()函数进行字符串转换 %s 有线使用str()函数进行字符串转换 %d or %i 转换成有符号十进制数 %u 转换成无符 ...
- Python中字符的编码与解码
1 文本和字节序列 我们都知道字符串,就是由一些字符组成的序列构成串,那么字符又是什么呢?计算机只能识别二进制的东西,那么计算机又为什么会显示我们的汉字,或者是某个字母呢? 由于最早发明使用计算机是美 ...
- python: json模块 --JSON编码和解码
json 源代码: Lib/json/__init__.py json.dump() import json numbers = [1, 2, 3, 4] with open('linshi.py', ...
- Python中的编码与解码(转)
Python中的字符编码与解码困扰了我很久了,一直没有认真整理过,这次下静下心来整理了一下我对方面知识的理解. 文章中对有些知识没有做深入的探讨,一是我自己也没有去深入的了解,例如各种编码方案的实现方 ...
随机推荐
- wince5.0 plat form builder下载
学习嵌入式开发的朋友都知道,嵌入式开发主要用到2个软件一个是Platform Builder for Windows CE 5.0一个是VS.NET2005,其中VS.NET2005网上很容易下载,现 ...
- javascript 获取http头信息
Javascript中跟response header有关的就两个方法: getResponseHeader 从响应信息中获取指定的http头 语法 strValue = oXMLHttpReques ...
- HDU 4372 - Count the Buildings(组合计数)
首先想过n^3的组合方法,即f(i,j,k)=f(i-1,j,k)*(i-2)+f(i-1,j-1,k)+f(i-1,j,k-1),肯定搞不定 然后想了好久没有效果,就去逛大神博客了,结果发现需要用到 ...
- 【笔记】关于jq $.ajax 函数 success回调函数不能赋正确值或返回正确值的问题
最近在一个项目里面打算实现如下功能: 当我注册账号的时候当输入账号完毕后输入框失焦时执行一个 ajax 请求,验证账号是否被注册,并未这个输入框的 isCorrect属性赋值,如果没有被注册 isCo ...
- 使用python语言编写脚本控制freeswitch总结
1. 在Linux环境下已经安装了freeswitch,(没安装freeswitch,请安装说明文档) 2. 进入源代码目录 cd libs/esl 目录下 首先安装 yum install p ...
- [Android] SQLite数据库之增删改查基础操作
在编程中常常会遇到数据库的操作,而Android系统内置了SQLite,它是一款轻型数据库,遵守事务ACID的关系型数据库管理系统,它占用的资源非常低,可以支持Windows/Linux/Un ...
- git 关联远程分支
问题解析: git本地新建一个分支后,必须要做远程分支关联.如果没有关联, git 会在下面的操作中提示你显示的添加关联.关联目的是如果在本地分支下操作: git pull, git push ,不需 ...
- .gnet标准
1 预祝 .gnet进军w3c!!!成为html5的标准 2 .gnet在进行压缩的时候.图片信息不会丢失 3 .gnet须要csdn.百度搜索.360.腾讯.新浪微博.各种视频软件的支持..! ...
- MySQL外键的设置及作用
原文地址:http://www.php100.com/html/webkaifa/database/Mysql/2010/0830/5342.html 外键的作用: 保持数据一致性,完整性,主要目的是 ...
- 用squid配置代理服务器(基于Ubuntu Server 12.04)
怀揣着为中小企业量身定做一整套开源软件解决方案的梦想开始了一个网站的搭建.http://osssme.org/ 1. 安装squid $sudo apt-get install squid -y 注: ...