进制运算、字符编码、Python3的执行流程

                                                  进制运算

  • 进制拾遗

           二进制:0、1

          八进制:0、1、2、3、4、5、6、7

          十进制:0、1、2、3、4、5、6、7、8、9

          十六进制:0、1、2、3、4、5、6、7、8、9 、A、B、C、D、E、F(分别表示10、11、12、13、14、15)

 1 #10进制转换8进制,以0o开头,逢7进1
 2 print(oct(1))             #结果为:0o1
 3 print(oct(2))             #结果为:0o2
 4 print(oct(3))             #结果为:0o3
 5 print(oct(7))             #结果为:0o7
 6 print(oct(8))             #结果为:0o10
 7 print(oct(15))            #结果为:0o17
 8 print(oct(16))            #结果为:0o20
 9 print(oct(64))            #结果为:0o100
10 
11 #0进制转换16进制,以0x开头,逢16进1
12 print(hex(1))              #结果为:0x1
13 print(hex(3))              #结果为:0x3
14 print(hex(9))              #结果为:0x9
15 print(hex(10))             #结果为:0xa
16 print(hex(11))             #结果为:0xb
17 print(hex(15))             #结果为:0xf
18 print(hex(16))             #结果为:0x10
19 print(hex(31))             #结果为:0x1f

                                                   

                                              为何使用 16 进制

                                         

                                             16进制与2进制的换算

  • 2进制换算为16进制

        四合一法(从二进制的小数点为分界点,向左(或向右)每四位取成一位)

                            

 

           注意16进制的表示法(用字母H后缀表示或者用0X前缀表示)

                     

            在向左(或向右)取四位时,取到最高位(最低位)如果无法凑足四位,就可以在小数点的最左边(或最右边)补0,然后再进行换算。

                   

  • 16进制转换为二进制

     一分为四法(一个十六进制数分成四个二进制数,用四位二进制按权相加,最后得到二进制,小数点依旧)

           

二进制数与十六进制数之间如何互相转换:https://jingyan.baidu.com/album/47a29f24292608c0142399cb.html?picindex=1

                                           字符编码回顾

                                   字符编码回顾:http://www.cnblogs.com/alex3714/articles/7550940.html

  • 编码的种类情况

  1.                ASCII                  占1个字节,只支持英文
  2.               GB2312                占2个字节,支持6700+汉字
  3.               GBK                     GB2312的升级版,支持21000+汉字
  4.               Shift-JIS               日本字符
  5.               ks_c_5601-1987    韩国编码
  6.              TIS-620                 泰国编码
  7.              由于每个国家都有自己的字符,所以其对应关系也涵盖了自己国家的字符,但是以上编码都存在局限性,即:仅涵盖本国字符,无其他国家字符的对应关系。应运而生出现了万国码,他涵盖了全球所有的文字和二进制的对应关系,
  8.               Unicode                  2-4字节 已经收录136690个字符,并还在一直不断扩张中。
  • Unicode 的作用

        直接支持全球所有语言,每个国家都可以不用再使用自己之前的旧编码了。

        unicode包含了跟全球所有国家编码的映射关系。

  • Unicode 的缺点

       使用unicode表示一个字符,太浪费空间,比原来ASCII表示多占用了1倍的空间。

       存储和网络传输时消耗资源。

  • UTF

      为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode中的进行转换,以便于在存储和网络传输时可以节省空间。

  1. UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个
  2. UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。
  3. UTF-32: 使用4个字节表示所有字符;

      总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。

                                           字符怎么存到硬盘上的?

           无论以什么编码在内存里显示字符,存到硬盘上都是2进制

           

        注意:存到硬盘上时是以何种编码存的,再从硬盘上读出来时,就必须以何种编码读。

                                           

                                         字符编码的转换

     虽然现在国际语言是英语 ,但大家在我们自己的国家说的依然是自己国家的语言。编码也是一样的,虽然有了 unicode 与 utf-8 ,但是各个国家依然在使用自己的编码。

     比如中国的windows系统默认编码依然是gbk,而不是utf-8。

     但是我们出了国,你就得会国际语言英语,不然没方法沟通呀!编码也是一样的,如果中国的软件出口到美国,他们的电脑上并没有gbk编码,那么在美国人的电脑上就会显示乱码。
     若想让中国的软件可以正常的在美国人的电脑上显示该怎么办呢?

  1. 让美国人的电脑上装上 gbk 编码。

  2. 编码时以 utf-8 或  unicode 编码。

    第1种方法几乎是不可能实现的,如此看来还是第2种方法比较简单些。

   但是第二种方法也只能是针对新开发的软件, 如果是之前就是以gbk编码的软件,重新编码成utf-8格式也会费很大力气,那要怎么办呢?

   unicode其中一个功能是其包含了跟全球所有国家编码的映射关系。

   也就是说,你写的是gbk的“路飞学城”,但是unicode能自动知道它在unicode中的“路飞学城”的编码是什么。那就意味着,无论你以什么编码存储的数据 ,只要你的软件在把数据从硬盘读到内存里,转成unicode来显示,就可以了。
   由于所有的系统、编程语言都默认支持unicode,那你的gbk软件放到美国电脑 上,加载到内存里,变成了unicode,中文就可以正常展示了。

unicode与gbk的映射表 :http://www.unicode.org/charts/ 

 

 

                                            Python3的执行流程 

  • Python3的执行过程 

              1、’解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode。

              2、把代码字符串按照语法规则进行解释。

              3、所有的变量字符都会以unicode编码声明。

 

  • python3编码转换过程

          实际代码演示,在py3上 把你的代码以utf-8编写, 保存,然后在windows上执行。

s = '路飞学城'
print(s)

 

          上面的utf-8编码之所以能在windows gbk的终端下显示正常,是因为到了内存里python解释器把utf-8转成了unicode。但是这只是python3, 并不是所有的编程语言在内存里默认编码都是unicode,比如python2 , 它的默认编码是ASCII。

         python2解释器仅以文件头声明的编码去解释你的代码,加载到内存后,并不会主动帮你转为unicode,也就是说,你的文件编码是utf-8,加载到内存里,你的变量字符串就也是utf-8, 这意味着,你以utf-8编码的文件,在windows是乱码。

乱是正常的,不乱才不正常,因为只有2种情况 ,你的windows上显示才不会乱:

1、字符串以GBK格式显示

2、字符串是unicode编码

  • python3编码转换语法

     python3 可以自动把文件编码转为 unicode必定是调用了什么方法。这个方法就是,decode(解码) 和 encode(编码)。

  1、UTF-8 --> decode 解码 --> Unicode

  2、Unicode --> encode 编码 --> GBK / UTF-8 

 记住下图规则

                                       

                                 Python3通过查看编码映射表确定编码类型

  • 如何验证编码转对了呢?

         1、查看数据类型,Python2里面有专门的unicode类型

         2、查看unicode编码映射表

  • 通过字节长度判断(utf-8一个中文占3字节,gbk一个占2字节)

         

       “路飞学城”的unicode编码的映射位置是 u'u8defu98deu5b66u57ce' 。
       “路飞学城”对应的GBK编码是'xc2xb7xb7xc9xd1xa7xb3xc7' 。2个字节一个中文,"路" 的二进制 "xc2xb7"是4个16进制,正好2字节,拿它到unicode映射表里对一下, 发现是G0-4237,并不是xc2xb7。

           

        再查下“飞” u98de ,对应的是G0-3749, 跟xb7xc9也对不上。

               

      虽然对不上, 但好xc2xb7 和G0-4237中的第2位的2和第4位的7对上了,“飞”字也是一样,莫非巧合? 

     把他们都转成2进制显示试试 

 1  2 C               2
 3 8   4   2   1   8   4   2   1
 4 <strong>1   1   0   0   0   0   1   0</strong>
 5 
 6 B               7
 7 8   4   2   1   8   4   2   1
 8 <strong>1   0   1   1   0   1   1   1</strong>
 9 
10 
11 12 B               7
13 8   4   2   1   8   4   2   1
14 1   0   1   1   0   1   1   1
15 
16 C               9
17 8   4   2   1   8   4   2   1
18 1   1   0   0   1   0   0   1

 但是这个“路”还是跟 G0-4237 对不上啊, 但如果把‘’路‘’ xc2xb7 的每个二进制字节的左边第一个bit变成0试试,然后发现加起来就真的是4237了。

之所以是这样,是因为GBK的编码表示形式决定的。因为GBK编码在设计初期就考虑到了要兼容ASCII,即如果是英文,就用一个字节表示,2个字节就是中文。

但如何区别连在一起的2个字节是代表2个英文字母,还是一个中文汉字呢?

中国人决定,2个字节连在一起,如果每个字节的第1位(也就是相当于128的那个2进制位)如果是1,就代表这是个中文,这个首位是128的字节被称为高字节。 也就是2个高字节连在一起,必然就是一个中文。

因为0-127已经表示了英文的绝大部分字符,128-255是ASCII的扩展表,表示的都是极特殊的字符,一般没什么用,所以中国人就直接拿来用了。 

问:那为什么上面 "xc2xb7"的2进制要把128所在的位去掉才能与unicode编码表里的G0-4237匹配上呢?

这只能说是unicode在映射表的表达上直接忽略了高字节,但真正映射的时候 ,肯定还是需要用高字节的哈。

原文地址:https://www.cnblogs.com/wqq0723/p/9534690.html