博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python与编码
阅读量:5116 次
发布时间:2019-06-13

本文共 3652 字,大约阅读时间需要 12 分钟。

编码的概念

  学习python已经半年了,回过头来看编码问题,发现它在我们学习过程中埋了很多雷,不完全搞懂python的编码在学习python的过程中还埋着很多潜在的雷呢。

文件从磁盘到内存的编码

  首先,抛开python解释器来说,就一般的应用程序(记事本等)来说,你写的文字还没有保存的时候是以什么形式存在在内存的呢?

  是Unicode二进制数据,他是内存编码的一种规范,实际上Unicode编码方式完全解决了全世界的文字编码问题,只是在将内存数据存储到硬盘的时候,Unicode数据占用空间要远大于utf8(编写代码,中文数据出现频率很低),当硬盘不变时,utf8的数据占空间更小,传输更快,所以utf解决了保存和传输数据的问题。

  所以,我们保存在磁盘上的数据是什么类型的?

  答案是通过某种编码方式编码的bytes字节串。由于历史遗留问题,在utf8之前还有gbk等一些字符编码方式存在。

    最早的时候计算机使用的编码规则是ASCII码,ASCII码最早是美国人使用的。ASCII码用一个字节的二进制组来表示一个字符(因为他们只用到26个引文字母和一些符号,最初的ASCII码甚至只用到7个bit位)。

    随着计算机的日益普及,ASCII码难以满足世界各地人们的使用,在中国就出现了GB2312与GBK的编码方式,使用两个字节的二进制组表示一个字符(甚至强硬的占用了拉美等国家的最高bit位)。正因为如此,世界各地都使用自己的编码方式,各自的软件都无法兼容了,所以就出现了万国码。

    万国码(Unicode)覆盖了全世界所有的文字,这也太强大了,那我们使用万国码不是很方便吗?但是对于美国人来说,他们只需要使用一个字节就可以表示所有的字符,而现在却平白无故多出一个字节,这使得内存与硬盘浪费了空间,所以Unicode优化成了现在的utf-8格式。utf-8是可变长的编码方式,所以现在开发倾向于使用这种编码方式。但是现在依然很多地方在使用GBK,ASCII等编码方式,所以对于编码我们需要详细的了解。

  回到应用程序上来,当我们执行保存文件的时候,应用程序有默认的编码方式将内存中的Unicode二进制数编码成bytes类型存储到硬盘,当我们再次打开应用程序的时候,它又以同样的编码方式将硬盘上的bytes数据解码成Unicode数据存放到内存,我们就可以以明文方式看到数据了。

  utf8这么好为什么我们内存中不使用utf8格式存放呢,一句话就是utf8不能直接转换成gbk等其他数据,但是Unicode可以直接编码成gbk等格式数据。

  Unicode与utf8的关系:

  Unicode是内存编码表示方案(是规范),而UTF是如何保存和传输Unicode的方案(是实现)这也是UTF与Unicode的区别。

  Unicode进行明文与二进制之间的转换,utf8进行二进制与二进制之间的数据转换打印unicode数据就会显示相应的明文(包括英文和中文)。

  python解释器与我们上面说的记事本程序的数据编码解码很类似。

  当我们保存的的时候,文件就以pycharm默认的编码方式保存到了磁盘;关闭文件后再打开,pycharm就再以默认的编码方式对该文件打开后读到的内容进行解码,转成unicode到内存我们就看到了我们的明文;(这个过程使用记事本也可以完成,在cmd中完成运行)

  而如果我们点击运行按钮或者在命令行运行该文件时,py解释器这个软件就会被调用,打开文件,然后解码存在磁盘上的bytes数据成unicode数据,这个过程和编辑器是一样的,不同的是解释器会再将这些unicode数据翻译成C代码再转成二进制的数据流,最后通过控制操作系统调用cpu来执行这些二进制数据,整个过程才算结束。

  以上就是完整的文件的编码,我们下面讲的python2与python3的字符串编码是在cpu执行程序时的存储状态,是另外一个过程,不要混淆!

python2的string编码

    python2中默认编码方式是ASCII码。

name = '杰夫'     #str类型为bytesname2 = u'杰夫'   #将字符串类型改为Unicodeprint  repr(name)print  repr(name2)运行结果'\xbd\xdc\xb7\xf2'u'\u6770\u592b'

    在python2中str字符串类型在内存中存的是bytes类型,Unicode类型字符串存储的是Unicode数据。

    

name = '杰夫'                #name为字节数据类型name2 = u'杰夫'            #name为unicode数据类型name3 = name.decode('utf8')name4 = name2.encode('utf8')print type(name3)print type(name4)print repr(name)print repr(name2)print repr(name3)print repr(name4)运行结果
'\xe6\x9d\xb0\xe5\xa4\xab' #str字符串类型的bytes数据u'\u6770\u592b' #Unicode字符串类型的Unicode数据u'\u6770\u592b' #str字符串类型解码成Unicode数据'\xe6\x9d\xb0\xe5\xa4\xab' #Unicode字符串类型编码成bytes数据

python3的string编码

    python3中默认的编码方式是utf-8.

name = b'jeff'name2 = '杰夫'print(type(name))print(repr(name))print(type(name2))print(repr(name2))运行结果
b'jeff'
'杰夫'

    python3中str字符串类型在内存中存的是Unicode数据,bytes类型字符串存储的是bytes数据。

name = b'jeff'name2 = '杰夫'name3=name.decode('utf8')name4=name2.encode('utf8')print(type(name))print(type(name2))print(type(name3))print(type(name4))print(repr(name))print(repr(name2))print(repr(name3))print(repr(name4))运行结果
b'jeff' #bytes类型字符串存储的bytes数据'杰夫' #str类型字符串存储的Unicode数据 'jeff' #bytes类型字符串解码成Unicode数据b'\xe6\x9d\xb0\xe5\xa4\xab' #str类型字符串编码城bytes数据

    简单的总结一下编码bytes数据是为了方便传输与存储,而Unicode数据方便了显示,python3比python2更加清晰化了字节与字符的界限,python3取消了python2中的不同类型字符串的拼接。

    因为编码方式的不同经常会出现下面这种情况。

    在python中写一个小程序,

#coding=utf8print('杰夫')

  在windows终端打开此文件。

这里显示出一堆乱码,这是为什么呢?

因为我的python3默认编码方式是utf-8,而我的windows终端默认解码方式是GBK,lianxi1.py这个文件内容在内存中以utf-8的编码方式写入硬盘,在cmd中执行时,cmd软件默认解码方式是GBK,用GBK的方式去解码utf-8的二进制数据,解码出来的就是一堆乱码,所以解决方法就是要么让cmd使用utf-8的方式来解码,否则就只能让python解释器用GBK方式将文件内容编码存入硬盘。

#coding=GBKprint('杰夫')

   http://www.cnblogs.com/yuanchenqi/p/5956943.html苑昊老师的博客里对于字符编码的详细解释写的非常棒,可以进行进一步参考。

转载于:https://www.cnblogs.com/Jeffding/p/7102262.html

你可能感兴趣的文章
7-1 抓老鼠啊~亏了还是赚了? (20 分)
查看>>
P2947 [USACO09MAR]向右看齐Look Up
查看>>
记录这个伟大的日子
查看>>
EasyUi-1 拖放
查看>>
莫比乌斯反演学习笔记
查看>>
OpenSceneGraph FAQ
查看>>
Java开发环境的配置
查看>>
Dijkstra算法——最短路径(转)
查看>>
《python可以这样学》第一章
查看>>
Andirod——网络连接(HttpURLConnection)
查看>>
oc27--synthesize,省略getset实现
查看>>
页面跳转控制
查看>>
[ActionScript 3.0] AS3 绘制12面体
查看>>
Python—json模块
查看>>
今天踩了一个低级坑
查看>>
百度前端技术学院-task1.8源代码
查看>>
db_index,unique和primary区别
查看>>
c++模板
查看>>
js null ,null没有typeof返回值为undefine 即 null没有返回类型的
查看>>
JDK1.8聚合操作
查看>>