巩义网站建设案例,哪里有做网站设计,怎么做网页连接,手机建站平台编码回顾 编码转换 Python的bytes类型 编码回顾 在备编码相关的课件时#xff0c;在知乎上看到一段关于Python编码的回答 这哥们的这段话说的太对了#xff0c;搞Python不把编码彻底搞明白#xff0c;总有一天它会猝不及防坑你一把。 不过感觉这哥们的答案并没把编码问题写明…编码回顾 编码转换 Python的bytes类型 编码回顾 在备编码相关的课件时在知乎上看到一段关于Python编码的回答 这哥们的这段话说的太对了搞Python不把编码彻底搞明白总有一天它会猝不及防坑你一把。 不过感觉这哥们的答案并没把编码问题写明白所以只好亲自动笔了。 折腾编码问题有很多次我以为自已明白了最终发现那只不过是自圆其说而已这一次终于100%确定动笔即不再改 看这篇文章前你应该已经知道了为什么有编码以及编码的种类情况 ASCII 占1个字节只支持英文GB2312 占2个字节支持6700汉字GBK GB2312的升级版支持21000汉字Shift-JIS 日本字符ks_c_5601-1987 韩国编码TIS-620 泰国编码由于每个国家都有自己的字符所以其对应关系也涵盖了自己国家的字符但是以上编码都存在局限性即仅涵盖本国字符无其他国家字符的对应关系。应运而生出现了万国码他涵盖了全球所有的文字和二进制的对应关系 Unicode 2-4字节 已经收录136690个字符并还在一直不断扩张中...Unicode 起到了2个作用 直接支持全球所有语言每个国家都可以不用再使用自己之前的旧编码了用unicode就可以了。(就跟英语是全球统一语言一样)unicode包含了跟全球所有国家编码的映射关系为什么呢后面再讲Unicode解决了字符和二进制的对应关系但是使用unicode表示一个字符太浪费空间。例如利用unicode表示“Python”需要12个字节才能表示比原来ASCII表示增加了1倍。 由于计算机的内存比较大并且字符串在内容中表示时也不会特别大所以内容可以使用unicode来处理但是存储和网络传输时一般数据都会非常多那么增加1倍将是无法容忍的 为了解决存储和网络传输的问题出现了Unicode Transformation Format学术名UTF即对unicode中的进行转换以便于在存储和网络传输时可以节省空间! UTF-8 使用1、2、3、4个字节表示所有字符优先使用1个字符、无法满足则使增加一个字节最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个其它及特殊字符占4个UTF-16 使用2、4个字节表示所有字符优先使用2个字节否则使用4个字节表示。UTF-32 使用4个字节表示所有字符总结UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。 字符在硬盘上的存储 无论以什么编码在内存里显示字符存到硬盘上都是2进制。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ascii编码(美国) l 0b1101100 o 0b1101111 v 0b1110110 e 0b1100101 GBK编码(中国) 老 0b11000000 0b11001111 男 0b11000100 0b11010000 孩 0b10111010 0b10100010 Shift_JIS编码(日本) 私 0b10001110 0b10000100 は 0b10000010 0b11001101 ks_c_5601-1987编码(韩国) 나 0b10110011 0b10101010 는 0b10110100 0b11000010 TIS-620编码(泰国) ฉัน 0b10101001 0b11010001 0b10111001 ... 1 要注意的是存到硬盘上时是以何种编码存的再从硬盘上读出来时就必须以何种编码读要不然就乱了。。 编码的转换 虽然国际语言是英语 但大家在自己的国家依然说自已的语言不过出了国 你就得会英语编码也一样虽然有了unicode and utf-8 但是由于历史问题各个国家依然在大量使用自己的编码比如中国的windows,默认编码依然是gbk,而不是utf-8 基于此如果中国的软件出口到美国在美国人的电脑上就会显示乱码因为他们没有gbk编码。若想让中国的软件可以正常的在 美国人的电脑上显示只有以下2条路可走 让美国人的电脑上都装上gbk编码 把你的软件编码以utf-8编码第1种方法几乎不可能实现第2种方法比较简单。 但是也只能是针对新开发的软件。 如果你之前开发的软件就是以gbk编码的上百万行代码可能已经写出去了重新编码成utf-8格式也会费很大力气。 so , 针对已经用gbk开发完毕的项目以上2种方案都不能轻松的让项目在美国人电脑上正常显示难道没有别的办法了么有 还记得我们讲unicode其中一个功能是其包含了跟全球所有国家编码的映射关系意思就是你写的是gbk的“路飞学城”,但是unicode能自动知道它在unicode中的“路飞学城”的编码是什么如果这样的话那是不是意味着无论你以什么编码存储的数据 只要你的软件在把数据从硬盘读到内存里转成unicode来显示就可以了。由于所有的系统、编程语言都默认支持unicode那你的gbk软件放到美国电脑 上加载到内存里变成了unicode,中文就可以正常展示啦。 这个表你自己也可以下载下来 unicode与gbk的映射表 http://www.unicode.org/charts/ Python3的执行过程 在看实际代码的例子前我们来聊聊python3 执行代码的过程 解释器找到代码文件把代码字符串按文件头定义的编码加载到内存转成unicode把代码字符串按照语法规则进行解释所有的变量字符都会以unicode编码声明编码转换过程 实际代码演示在py3上 把你的代码以utf-8编写 保存然后在windows上执行 1 2 s 路飞学城 print(s) so ,一切都很美好到这里我们关于编码的学习按说就可以结束了。 但是如生活一样美好的表面下总是隐藏着不尽如人意上面的utf-8编码之所以能在windows gbk的终端下显示正常是因为到了内存里python解释器把utf-8转成了unicode , 但是这只是python3, 并不是所有的编程语言在内存里默认编码都是unicode,比如 万恶的python2 就不是 它的默认编码是ASCII想写中文就必须声明文件头的coding为gbk or utf-8, 声明之后python2解释器仅以文件头声明的编码去解释你的代码加载到内存后并不会主动帮你转为unicode,也就是说你的文件编码是utf-8,加载到内存里你的变量字符串就也是utf-8, 这意味着什么你知道么。。。意味着你以utf-8编码的文件在windows是乱码。 乱是正常的不乱才不正常因为只有2种情况 你的windows上显示才不会乱 字符串以GBK格式显示字符串是unicode编码既然Python2并不会自动的把文件编码转为unicode存在内存里 那就只能使出最后一招了你自己人肉转。Py3 自动把文件编码转为unicode必定是调用了什么方法这个方法就是decode(解码) 和encode(编码) 1 2 UTF-8 -- decode 解码 -- Unicode Unicode -- encode 编码 -- GBK / UTF-8 .. decode示例 encode 示例 记住下图规则 如何验证编码转对了呢 1. 查看数据类型python 2 里有专门的unicode 类型2. 查看unicode编码映射表 unicode字符是有专门的unicode类型来判断的但是utf-8,gbk编码的字符都是str,你如果分辨出来的当前的字符串数据是何种编码的呢 有人说可以通过字节长度判断因为utf-8一个中文占3字节gbk一个占2字节 靠上面字节个数虽然也能大体判断是什么类型但总觉得不是很专业。 怎么才能精确的验证一个字符的编码呢就是拿这些16进制的数跟编码表里去匹配。 “路飞学城”的unicode编码的映射位置是 u\u8def\u98de\u5b66\u57ce ‘\u8def’ 就是‘路’到表里搜一下。“路飞学城”对应的GBK编码是\xc2\xb7\xb7\xc9\xd1\xa7\xb3\xc7 2个字节一个中文路 的二进制 \xc2\xb7是4个16进制正好2字节拿它到unicode映射表里对一下 发现是G0-4237并不是\xc2\xb7呀。。。擦。演砸了吧。。 再查下“飞” \u98de 对应的是G0-3749 跟\xb7\xc9也对不上。 虽然对不上 但好\xc2\xb7 和G0-4237中的第2位的2和第4位的7对上了“飞”字也是一样莫非巧合 把他们都转成2进制显示试试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 路 C 2 8 4 2 1 8 4 2 1 strong1 1 0 0 0 0 1 0/strong B 7 8 4 2 1 8 4 2 1 strong1 0 1 1 0 1 1 1/strong 飞 B 7 8 4 2 1 8 4 2 1 1 0 1 1 0 1 1 1 C 9 8 4 2 1 8 4 2 1 1 1 0 0 1 0 0 1 这个“路”还是跟G0-4237对不上呀没错 但如果你把路\xc2\xb7的每个二进制字节的左边第一个bit变成0试试呢 我擦加起来就真的是4237了呀。。难道又是巧合 必然不是是因为GBK的编码表示形式决定的。。因为GBK编码在设计初期就考虑到了要兼容ASCII,即如果是英文就用一个字节表示2个字节就是中文但如何区别连在一起的2个字节是代表2个英文字母还是一个中文汉字呢 中国人如此聪明决定2个字节连在一起如果每个字节的第1位(也就是相当于128的那个2进制位)如果是1就代表这是个中文这个首位是128的字节被称为高字节。 也就是2个高字节连在一起必然就是一个中文。 你怎么如此笃定因为0-127已经表示了英文的绝大部分字符128-255是ASCII的扩展表表示的都是极特殊的字符一般没什么用。所以中国人就直接拿来用了。 问那为什么上面 \xc2\xb7的2进制要把128所在的位去掉才能与unicode编码表里的G0-4237匹配上呢 这只能说是unicode在映射表的表达上直接忽略了高字节但真正映射的时候 肯定还是需要用高字节的哈。 Python bytes类型 在python 2 上写字符串 1 2 3 4 5 s 路飞 print s 路飞 s \xe8\xb7\xaf\xe9\xa3\x9e 虽说打印的是路飞但直接调用变量s看到的却是一个个的16进制表示的二进制字节我们怎么称呼这样的数据呢直接叫二进制么也可以 但相比于010101这个数据串在表示形式上又把2进制转成了16进制来表示这是为什么呢 哈为的就是让人们看起来更可读。我们称之为bytes类型即字节类型 它把8个二进制一组称为一个byte,用16进制来表示。 说这个有什么意思呢 想告诉你一个事实 就是python2的字符串其实更应该称为字节串。 通过存储方式就能看出来 但python2里还有一个类型是bytes呀难道又叫bytes又叫字符串 嗯 是的在python2里bytes str 其实就是一回事 除此之外呢 python2里还有个单独的类型是unicode , 把字符串解码后就会变成unicode 1 2 3 4 5 6 s \xe8\xb7\xaf\xe9\xa3\x9e #utf-8 s.decode(utf-8) u\u8def\u98de #unicode 在unicode编码表里对应的位置 print(s.decode(utf-8)) 路飞 #unicode 格式的字符 由于Python创始人在开发初期认知的局限性其并未预料到python能发展成一个全球流行的语言导致其开发初期并没有把支持全球各国语言当做重要的事情来做所以就轻佻的把ASCII当做了默认编码。 当后来大家对支持汉字、日文、法语等语言的呼声越来越高时Python于是准备引入unicode,但若直接把默认编码改成unicode的话是不现实的 因为很多软件就是基于之前的默认编码ASCII开发的编码一换那些软件的编码就都乱了。所以Python 2 就直接 搞了一个新的字符类型就叫unicode类型比如你想让你的中文在全球所有电脑上正常显示在内存里就得把字符串存成unicode类型 1 2 3 4 5 6 7 8 s 路飞 s \xe8\xb7\xaf\xe9\xa3\x9e s2 s.decode(utf-8) s2 u\u8def\u98de type(s2) type unicode 时间来到2008年python发展已近20年创始人龟叔越来越觉得python里的好多东西已发展的不像他的初衷那样开始变得臃肿、不简洁、且有些设计让人摸不到头脑比如unicode 与str类型str 与bytes类型的关系这给很多python程序员造成了困扰。龟叔再也忍不了像之前一样的修修补补已不能让Python变的更好于是来了个大变革Python3横空出世不兼容python2,python3比python2做了非常多的改进其中一个就是终于把字符串变成了unicode,文件默认编码变成了utf-8,这意味着只要用python3,无论你的程序是以哪种编码开发的都可以在全球各国电脑上正常显示真是太棒啦 PY3 除了把字符串的编码改成了unicode, 还把str 和bytes 做了明确区分 str 就是unicode格式的字符 bytes就是单纯二进制啦。 最后一个问题为什么在py3里把unicode编码后字符串就变成了bytes格式 你直接给我直接打印成gbk的字符展示不好么我想其实py3的设计真是煞费苦心就是想通过这样的方式明确的告诉你想在py3里看字符必须得是unicode编码其它编码一律按bytes格式展示。 好吧就说这么多吧。 最后再提示一下Python只要出现各种编码问题无非是哪里的编码设置出错了常见编码错误的原因有 Python解释器的默认编码Python源文件文件编码Terminal使用的编码操作系统的语言设置掌握了编码之前的关系后挨个排错就好啦 更多详见http://www.cnblogs.com/alex3714/articles/7550940.html http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html转载于:https://www.cnblogs.com/tlios/p/7634799.html