python 第二章 二进制运算、字符编码、数据类型
>>> len(s.ljust(50,'*'))
50
>>>
1.二进制转换:
bin(342)
'0b101010110'
2.ASCII码与二进制:
每一个ASCII码都是用8位表示,ASCII码一共有255个。每一位0或者1所占的空间单位为bit(比特),这是计算机中最小的表示单位,8位表示一个字节。
8bit = 1bytes(字节),最小的存储单位,1bytes缩写为1B
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
1EB = 1024PB
1ZB = 1024EB
1YB = 1024ZB
1BB = 1024YB
3.python 字符编码的演化:
GB2312 又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。共7445个图形字符,其中汉字占6763个。
1995年发布GBK1.0,gbk编码能够用来同时表示繁体字和简体字,该编码标准兼容GB2312,共收录汉字21003个,同时包含中日韩所文字里所有汉字。
2000年发布GB18030,是对GBK编码的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录27484个汉字。兼容GBK和GB2312字符集。
BIG5编码:台湾地区繁体字中文标准字符集,采用双字节编码,共收录13053个中文字,1984年实施。
Unicode编码(1991年):国际标准字符集,它将世界各种语言的每一个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。Unicode(统一码、万国码)规定所有的字符和 符号最少由16位来表示(2字节)。
UTF-8,是对Unicode编码的压缩和优化,他不再使用最少使用2给字节,而是将所有的字符和符号进行分类:ascii码中的内容用1给字节保存、欧洲的字符用2给字节保持,东亚的字符用3个 字节保存。。。
4.python 里使用编码:
python2使用的编码是ASCII码,python3使用的编码是UTF-8,python里编码声明: #! -*- coding: utf-8 -*- 或 #!encoding:utf-8
5.浮点数和科学计数法:
浮点数是属于有理数中某特定子集的数字表示,在计算机中用以近似表示任意某给实数。具体的说,这个实数由一个整数或定点数(既尾数)乘以某个基数的整数次幂得到(10**4,10为基 数),这种表示方法类似于基数为10的科学计数法。
实数:有理数和无理数
有理数:正有理数、负有理数和零
正有理数:正整数和正分数
负有理数:负整数和负分数
无理数:正无理数和负无理数
科学计算法: 1999000 = 1.999e6
复数是指能携程如下形式的数 a+bi,这里a和b是实数,i 是虚拟单位(即-1开根)。在复数 a+bi中,a称为复数的实部,b 称为复数的虚部,i 称为虚数单位。当虚部等于零时,这个复数计 算实数,当虚部不等于零时,这个复数称为虚数。
例如:(-5+4j)和(2.3-4.6j)都是复数例子。(计算量子力学用,程序员一般用不到)
6.浮点数的精度问题:
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的而浮点数运算则可能会有四舍五入的误差。
python默认的是17位精度,也就是小数点后16位,尽管有16位,但是这个精确度却是越往后越不准的。这个问题不只是只存在在python中,其他语言也有同样的问题。原因与浮点数存储结 构有关。
编程需要浮点数特别精确的话需要导入第三方库。
7.列表类型:
列表是一个数据的集合,集合内可以放任何数据类型,可对集合进行方便的增删改查操作,L1 = [ ] #定义空列表 ,L2 = ['a', 'b', 'c', 'd'] #存4个值,索引为0-3,L3 = ['abc', ['def', 'ghi']] #嵌 套列表
列表的创建:
L = [ ] ,L = list() 或 L = ['a', 'b']
列表的查询:
例如:L2 = ['a', 'b', 'c', 'd', 'a', 'e', 1, 2 ]
>>>L2[2] #通过索引取值
‘c’
>>>L2[-1] #通过索引从列表右边开始取值
2
>>>L2[-2]
1
>>>L2.index('a') #返回指定元素的索引值,从左右查找,找到第一个匹配
0 #这个是索引值
>>>L2.count('a') #统计指定元素的个数
2 #元素的数量
列表类型-修改及插入:
插入
例如:L2 = ['a', 'b', 'c', 'd', 'a', 'e', 1, 2 ]
>>>L2.append('alex') #追加
>>>L2
['a', 'b', 'c', 'd', 'a', 'e', 1, 2, 'alex' ]
>>>L2.insert(0, 'abc') # 括号里的前面的0是索引也就是插入的位置 ,abc是值
>>>L2
['abc', 'a', 'b', 'c', 'd', 'a', 'e', 1, 2, 'alex' ]
修改
例如: L2 = ['abc', 'a', 'b', 'c', 'd', 'a', 'e', 1, 2, 'alex' ]
>>>L2[-1]
>>>'alex'
>>>L2[-1] = 'Peiqi'
>>>L2
['abc', 'a', 'b', 'c', 'd', 'a', 'e', 1, 2, 'Peiqi' ]
批量修改(很少用)
>>>L2[4:6]
['d', 'a']
>>>L2[4:6] = 'alex liu'
>>>L2
['abc', 'a', 'b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2, 'Peiqi' ]
列表删除
例如:L2 =['abc', 'a', 'b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2, 'Peiqi' ]
>>>L2
['abc', 'a', 'b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2, 'Peiqi' ]
>>>L2.pop() #删除最后一个元素
'Peiqi'
>>>L2
['abc', 'a', 'b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2]
>>>L2.remove('abc') #删除指定的一个元素 从左到右数的第一个。
>>>L2
['a', 'b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2]
>>>L2.remove('a')
>>>L2
['b', 'c', a', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2]
>>>del L2[2] # 括号里的2是索引,del 是python全局性的删除命令不单可以删列表里的内容还可以删除整个列表等。
>>>L2
['b', 'c', 'l', 'e', 'x', 'l', 'i', 'u', 'e', 1, 2]
>>>del L2[:3]
>>>L2
['e', 'x', 'l', 'i', 'u', 'e', 1, 2]
列表循环
例如:
>>>L2 = ['a', 'b', 'c', 'L', 'I', 'e', 1, 2]
for i in L2:
print(i)
a
b
c
L
I
e
1
2
>>>
>>>L2.remove(1)
>>>L2.remove(2)
>>>L2
['a', 'b', 'c', 'L', 'I', 'e']
>>>L2.append('x')
>>>L2.insert(0, 'z')
>>>L2
['z', 'a', 'b', 'c', 'L', 'I', 'e', 'x']
>>>L2.insert(3,'A')
>>>L2
['z', 'a', 'b','A', 'c', 'L', 'I', 'e', 'x']
>>>L2.sort() #排序是按Ascii码的顺序来排
>>>L2
['A', 'I', 'L', 'a', 'b', 'c', 'e', 'x', 'z']
>>> L2.insert(2,'*')
>>> L2.insert(5,'#')
>>> L2.insert(3,'!')
>>> L2
['A', 'I', '*', '!', 'L', 'a', '#', 'b', 'c', 'e', 'x', 'z']
>>> L2.sort()
>>> L2
['!', '#', '*', 'A', 'I', 'L', 'a', 'b', 'c', 'e', 'x', 'z']
>>>
>>> L2.reverse() # 倒序排列
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!']
>>>
>>> L1 = [5, 8, 9]
>>> L1
[5, 8, 9]
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!']
>>> L2 + L1
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!', 5, 8, 9]
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!']
>>> L2.extend(L1) #扩展
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!', 5, 8, 9]
>>>
>>>L1.clear() # 清空列表
>>> L1
[5, 8, 9]
>>> L1.clear()
>>> L1
[]
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!', 5, 8, 9]
>>> L1 = L2.copy()
>>> L1
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!', 5, 8, 9]
>>> L2
['z', 'x', 'e', 'c', 'b', 'a', 'L', 'I', 'A', '*', '#', '!', 5, 8, 9]
copy # 是完全独立的
8.python 深浅COPY:
查看内存地址的命令是ID,例如:a = 1 , id(a) 返回值 140367631491920
列表copy命令如示:n2 = names.copy ,copy是两个独立的内存地址,互不影响。
n2 = names 这样的两个列表是指向同一个内存地址 ,一个发生改变另个也会跟着改变的。
9.python 字符串类型:
字符串是一个有序的字符的集合,用于存储和表示基本的文本信息,一对单、双、或三引号中间包含的内容称之为字符串。(有序不可变)!
swapcase() # 是大写变小写小写变大写!
capitalize() #首字母大写其他小写!
casefold() # 就是把大写 变成统一的小写!
center(参数,参数) # 括号里第一个参数是长度,第二个是填充的任意符号、字母或数字!
count(参数,star=Note,end=Note) #参数是要统计该参数的数量!star 是起始索引 ,end是结束索引!
endswith() #判断以什么结尾!返回布尔值!
expandtabs(长度) #tab键的长度!
find(参数,star=Note,end=Note)# 参数是要找的内容并返回索引值!star 是起始索引 ,end是结束索引!
format()# 例如:
>>> s = 'my names is {0}, i am {1} years old '
>>> s
'my names is {0}, i am {1} years old '
>>> s.format('kingforn', 22)
'my names is kingforn, i am 22 years old '
>>>
>>> s = 'my names is {name}, i am {age} years old '
>>> s
'my names is {name}, i am {age} years old '
>>> s.format(name='kingforn', age=22 )
'my names is kingforn, i am 22 years old '
>>>
index(参数,star=Note,end=Note)#跟列表的index一样用,返回索引值!也有起始和结束!
isalnum()# 是阿拉伯数字和字母返回是真,其他为假!
isalpha()#是字母返回是真,其他为假!
isdecimal()和isdigit() # 是整数是返回是真,小数和其他返回假!
isidentifier()# 检测是否是合法的变量,合法返回真!
islower()# 检测如果不包括大写返回就是真!
isprintable()#说这个值是否可以被打印!
istitle() # 首字母是大写返回真!
isupper()# 是否都是大写,都是大写返回真!
join() # 列表变成字符串
例如:>>> names = ['alex', 'coco', 'jack']
>>> ' '.join(names)
'alex coco jack'
>>> ''.join(names)
'alexcocojack'
>>> '-'.join(names)
'alex-coco-jack'
>>> ','.join(names)
'alex,coco,jack'
>>>
ljust()#例如: >>> s = 'Hello World'
>>> s
'Hello World'
>>> s.ljust(50)
'Hello World '
>>> s.ljust(50,'*')
'Hello World***************************************'
>>> len(s.ljust(50,'*'))
50
>>>
lower() #例如:
>>> a
'HELLO WORLD'
>>> a.lower()
'hello world'
>>>
upper() #例如:
>>> s
'hello world'
>>> s.upper()
'HELLO WORLD'
>>>
strip() #例如:lstrip() #左脱 , rstrip()# 右脱
>>> s = '\n hello world'
>>> s
'\n hello world'
>>> print(s)
hello world
>>> s.strip()
'hello world'
>>>
maketrans()和translate()#例如:
>>> str_in = 'abcdefg'
>>> str_out = ')(*&^%$'
>>> str.maketrans(str_in, str_out)
{97: 41, 98: 40, 99: 42, 100: 38, 101: 94, 102: 37, 103: 36}
>>> table = str.maketrans(str_in, str_out)
>>> table
{97: 41, 98: 40, 99: 42, 100: 38, 101: 94, 102: 37, 103: 36}
>>> s
'\n hello world'
>>> s.translate(table)
'\n h^llo worl&'
>>>
replace()# 替换例如:
>>> s
'\n hello world'
>>> s.replace('h','H')
'\n Hello world'
>>> s.replace('o', '-')
'\n hell- w-rld'
>>> s.replace('o', '-',1)
'\n hell- world'
>>>
split() #字符串变列表:
>>> s
'hello world'
>>> s.split()
['hello', 'world']
>>> s.split('o')
['hell', ' w', 'rld']
>>> s.split('l')
['he', '', 'o wor', 'd']
>>>
zfill() #例如:
>>> s
'hello world'
>>> s.zfill(50)
'000000000000000000000000000000000000000hello world'
>>>
常用的有:isdigit,replace,find,count,strip,center,split,format,join(必须掌握)
10.python 元组类型:
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表,它是有序的不可变的列表。
例如: names = (‘kingforn’, 'jack', 'alex')
特性:
元组本身不可变,如果元组中还包含其他可变元素,这些可变元素可以改变。
功能:
. index
. count
. 切片
使用场景:
. 显示的告知别人,此处数据不可修改。
. 数据库连接配置信息等。
11.hash函数:
hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是吧任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空 间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
特征:
hash值的计算过程是依据这个值的一些特征计算的,这就要求被hash的值必须固定,因此被hash的值必须是不可变的。
用途:
文件签名
MD5加密
密码验证
不可变类型有:数字,字符串,元组。
语法:
>>> hash ('abc')
2928505337467294543
>>> name = 'kingforn'
>>> hash(name)
5318639549762924456
>>>
12.python 字典类型及特性:
字典是一种key-value 的数据类型,使用就像我们上学用的字典,通过壁画字母来查对应页的详细内容。
特性:
. key-value结构
. key必须可hash、且必须为不可变数据类型、必须唯一
. 可存放任意多个值、可修改、可以不唯一
. 无序
. 查找速度快
13.python 字典的增删改查循环:
增:
>>>s = {'name1': 'kingforn', 'name2': 'alex', 'names': ['jack', 'shanshan']}
>>>s['name3'] = '苍井空'
>>>s
{'name1': 'kingforn', 'name2': 'alex', 'names': ['jack', 'shanshan'], 'name3': '苍井空'}
改:
>>>s['name3'] = '龙婷'
>>>s
{'name1': 'kingforn', 'name2': 'alex', 'names': ['jack', 'shanshan'], 'name3': '龙婷'}
查找:
>>>'name3' in s #标准用法
True
>>>s.get('name1') #获取
‘kingforn’
>>>s['name1'] #同上,但是看下面
'kingforn'
>>>s['name4'] #如果一个key不存在,就报错,get不会 会返回一个None(还可以自己自定义返回值)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'name4'
>>>
删除:
.clear() #是清空
.pop('参数') #
>>> s
{'name1': 'kingforn', 'name2': 'alex', 'names': ['jack', 'shanshan']}
>>> s.pop('name2')
'alex'
>>>
.popitem() #随机删
del # 例如:>>>del s['name1']
字典的循环:
>>> for k in s:
... print(k)
name1
names
>>> for k in s:
... print(k, s[k])
name1 kingforn
names ['jack', 'shanshan']
>>>
14.python 集合:
集合是一个无序的,不重复的数据组合,它的主要作用如下:
. 去重,把一个列表变成集合,就自动去重了。
. 关系测试, 测试两组数据之间的交集、差集、并集等关系。
集合中的元素有三个特征:
1.确定性(元素必须可hash)
2.互异性(去重)
3.无序性(集合中的元素没有先后之分),如集合{3,4,5}和{5,4,3}算作同一个集合。
增:
>>> s
{1, 2, 3, 5, 6, 8, 9}
>>> s.add(10)
>>> s
{1, 2, 3, 5, 6, 8, 9, 10}
>>>
>>> s
{2, 3, 5, 6, 9}
>>> s.update([5,6,11,12,13,15]) #增加多给值
>>> s
{2, 3, 5, 6, 9, 11, 12, 13, 15}
>>>
删:
>>> s.pop() #随机删
1
>>> s
{2, 3, 5, 6, 8, 9, 10}
>>>
>>> s.remove(8) #指定删
>>> s
{2, 3, 5, 6, 9, 10}
>>>
>>> s
{2, 3, 5, 6, 9, 10}
>>> s.discard(20) #删除不会报错
>>> s
{2, 3, 5, 6, 9, 10}
>>> s.discard(10)
>>>
15.python 集合类型的关系测试:
集合分:交集、差集、并集和对称差集
交集:intersection()
>>> iphone7 = {'kingforn','alex','jack','rain','old_driver'}
>>> iphone8 = {'kingforn','shanshan','old_boy','alex','amy'}
>>> iphone7.intersection(iphone8)
{'kingforn', 'alex'}
>>> iphone7 & iphone8
{'kingforn', 'alex'}
>>>
差集:difference()
>>> iphone7.difference(iphone8)
{'rain', 'jack', 'old_driver'}
>>> iphone7 - iphone8
{'rain', 'jack', 'old_driver'}
>>>
>>> iphone8.difference(iphone7)
{'old_boy', 'shanshan', 'amy'}
>>> iphone8 - iphone7
{'old_boy', 'shanshan', 'amy'}
>>>
并集:union()
>>> iphone7.union(iphone8)
{'jack', 'amy', 'kingforn', 'rain', 'shanshan', 'old_driver', 'alex', 'old_boy'}
>>> iphone7|iphone8
{'jack', 'amy', 'kingforn', 'rain', 'shanshan', 'old_driver', 'alex', 'old_boy'}
>>>
对称差集:symmetric_difference()
>>> iphone7.symmetric_difference(iphone8)
{'jack', 'amy', 'old_driver', 'old_boy', 'shanshan', 'rain'}
>>> iphone7 ^ iphone8
{'jack', 'amy', 'old_driver', 'old_boy', 'shanshan', 'rain'}
>>>
集合其他:
set.isdisjoint(s): 判断两个集合是不是不相交
set.issuperset(s):判断集合是不是包含其他集合,等同于a>b
set.issubset(s):判断集合是不是被其他集合包含,等同于a<b
16.十六进制运算:
二进制:01
八进制:01234567
十进制:0123456789
十六进制:0123456789ABCDEF
十进制转换8、16进制语法:
oct() #8进制
hex()#16进制
17.为什么要用16进制:
1.计算机硬件是0101二进制的,16进制刚好是2的倍数,更容易表达一个命令或者数据。十六进制更简短,因为换算的时候一位16进制数可以顶4位2进制数,也就是一个字节(8位进制可 以用两个16进制表示)
2.最早规定ASCII字符集采用的就是8bit(后期扩展了,但是基础单位还是8bit),8bit用2个16进制直接就能表达出来,不管阅读还是存储都比其他进制要方便。
3.计算机中CPU运算也是遵照ASCII字符集,以16、32、64的作用的方式在发展,因此数据交换的时候16进制也显得更好。
4.为了统一规范,CPU、内存、硬盘我们看到的都是采用的16进制计算。
16进制用在哪里:
1.网络编程,数据交换的时候需要对字节进行解析都是一个byte一个byte的处理,1个byte可以用0xff两个16进制来表达。通过网络抓包,可以看到数据是通过16进制的传输。
2.数据存储,存储到硬件中是0101的方式,存储到系统中的表达方式都是byte方式。
3.一些常用的值的定义,比如:我们经常用到的html中color表达,就是用的16进制方式,4给16进制位可以表达好几百倍的颜色信息。
17.16进制与二进制的换算:
二进制转换成十六进制的方法是,取四合一法,既从二进制的小数点为分界点向左(或向右)每四位取成一位。分组好以后,对照二进制与十六进制数的对应表,将四位二进制按权相 加,得到的数就是一位十六进制数,然后按顺序排列,小数点位置不变哦,最后得到的就是十六进制数。
18.python 字符编码回顾:
http://www.cnblogs.com/alex3714/articles/7550940.html
一旦走上了编程之路,如果你不把编码问题搞清楚,那么它将像幽灵一般纠缠你整个职业生涯,各种灵异事件会接踵而来,挥之不去。只有充分发挥程序员死磕到底的精神你才有可能彻 底摆脱编码问题带来的烦恼。搞python不把编码彻底搞明白,总有一天它会猝不及防坑你一把。
. ASCII 占1给字节,只支持英文
.GB2312 占2个字节,支持6700+汉字
.GBK GB2312的升级版,支持21000+汉字
.Shift-JIS 日本字符
.ks_c_5601-1987 韩国编码
.TIS-620 泰国编码
由于每个国家都有自己的字符,所以其对应关系也涵盖了自己国家的字符,但是以上编码都存在局限性,即:仅涵盖本国字符,无其他国家字符的对应关系。应运而生出现了万国 码,他涵盖了全球所有的蚊子和二进制的对应关系。
.unicode 2-4字节已经收录136690个字符,并还在一直不断扩张中。。。。
unicode 起到了2个作用:
1.直接支持全球所有语言,每个国家都可以不用使用自己之前的旧编码了,用Unicode就可以了。
2.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编码 设计 的一种 在存储 和传输时节省空间的编码方案。
19.python 字符串怎么存到硬盘上:
要注意的是,存到硬盘上时是以何种编码存的,再从硬盘上读出来时,就必须以何种编码读,要不然就乱了。。
20.python字符编码的转换:
虽然国际语言是英语 ,但大家在自己的国家依然说自已的语言,不过出了国, 你就得会英语
编码也一样,虽然有了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,中文就可以正常展示啦。
20.python3代码执行流程:
在看实际代码的例子前,我们来聊聊,python3 执行代码的过程
- 解释器找到代码文件,把代码字符串按文件头定义的编码加载到内存,转成unicode
- 把代码字符串按照语法规则进行解释,
- 所有的变量字符都会以unicode编码声明
21.python3通过查看编码映射表确定编码类型:
既然Python2并不会自动的把文件编码转为unicode存在内存里, 那就只能使出最后一招了,你自己人肉转。Py3 自动把文件编码转为unicode必定是调用了什么方法,这个方法就 是,decode(解码) 和encode(编码)
1. 查看数据类型,python 2 里有专门的unicode 类型
2. 查看unicode编码映射表
unicode字符是有专门的unicode类型来判断的,但是utf-8,gbk编码的字符都是str,你如果分辨出来的当前的字符串数据是何种编码的呢? 有人说可以通过字节长度判断,因为utf-8一个中 文占3字节,gbk一个占2字节
GBK的编码表示形式决定的。。因为GBK编码在设计初期就考虑到了要兼容ASCII,即如果是英文,就用一个字节表示,2个字节就是中文,但如何区别连在一起的2个字节是代表2个英文字 母,还是一个中文汉字呢? 中国人如此聪明,决定,2个字节连在一起,如果每个字节的第1位(也就是相当于128的那个2进制位)如果是1,就代表这是个中文,这个首位是128的字节被称 为高字节。 也就是2个高字节连在一起,必然就是一个中文。 你怎么如此笃定?因为0-127已经表示了英文的绝大部分字符,128-255是ASCII的扩展表,表示的都是极特殊的字符,一般 没什么用。所以中国人就直接拿来用了
22.python bytes类型介绍:
py2
Str = bytes
为什么有bytes?
是因为要表示图片、视频等二进制格式的数据
以utf-8编码的字符串,在windows上不能显示
s = you_str.decode('utf-8')
unicode类型
文件头:声明编码
py2:以utf-8 or gbk。。编码的代码,代码内容加载到内存,并不会被转成unicode,编码依然是UTF-8 or gbk。。。
py3:以utf-8 or gbk。。编码的代码,代码内容加载到内存,会被自动转成unicode,
py3 默认类型:
str = Unicode