python编码问题
主要内容:
1. is和==的区别
2. 编码的问题
id()函数
id 主要是获取变量的内存地址.
这里要了解一下赋值的内存变化,
示例如下:
a = ["abc"]
b = a
这里变量存储的只是内存地址信息,赋值a传给b的也是内存地址信息.所以当b内容发生变化后,a的内容也会发生变化.
b.append("ddd")
print(a) #那么a也会发生变化,因为是共用的一个地址.
代码看如下:
a = ["abc"] b = a b.append("ddd") print(a) # 运行结果 ['abc', 'ddd']
小数据池优化的问题
我们做如下测试,通过id()查看内存地址变化,会发现如下问题
a = 123
b = 123
print(id(a),id(b))
会发现内存地址是一样的.代码和执行结果如下:
a = 123 b = 123 print(id(a),id(b)) #代码执行结果如下:1897120640 1897120640
这里是因为python做了一个数据优化问题,相当于弄了一个块内存区域,用户缓存变量信息.主要目的优化内存利用.
关键问题是python对哪些数据类型和具体的值进行的优化.
主要优化了int和str两种类型.int型的值在-5-256之间,str型主要常用字符进行了优化.(不包含特殊字符一般都有优化.)
关于数据优化的详细总结如下:
⼩小数据池(常量量池): 把我们使⽤用过的值存储在⼩小数据池中.供其他的变量量使⽤用.
⼩小数据池给数字和字符串串使⽤用, 其他数据类型不存在.
对于数字: -5~256是会被加到⼩小数据池中的. 每次使⽤用都是同⼀一个对象.
对于字符串串:
1. 如果是纯⽂文字信息和下划线. 那么这个对象会被添加到⼩小数据池
2. 如果是带有特殊字符的. 那么不会被添加到⼩小数据池. 每次都是新的
3. 如果是单⼀一字⺟母*n的情况. 'a'*20, 在20个单位内是可以的. 超过20个单位就不会添加
到⼩小数据池中
注意(⼀一般情况下): 在py⽂文件中. 如果你只是单纯的定义⼀一个字符串串. 那么⼀一般情况下都是会
被添加到⼩小数据池中的. 我们可以这样认为: 在使⽤用字符串串的时候, python会帮我们把字符串串
进⾏行行缓存, 在下次使⽤用的时候直接指向这个字符串串即可. 可以节省很多内存.
is 和 ==的区别
is主要对比的是内存地址.
==对比的是变量内容.
有如下示例:
a = "abc" b = "abc" print(a is b) #比内存地址 print(a == b) #比内容 a = (1,2) b = (1,2) print( a is b) #比内存地址,这个是不同的 结果为False print( a == b) #这个内容是相同的,结果是True a = ["123"] b = a b.append(456) print(a is b) #赋值的话内存地址是一样的.所以为True print(a == b) # 两个变量的内存地址都是一样的了,内容肯定是一样的了.
编码问题
计算机常用编码主要有下面几种(我们常用的几种)
ASCII 码 GBK 国标码 Unicode 万国码 UTF-8码
数据和文件在存储和传输过程中只能用非unicode码来处理,因为unicode太大了,不适合作存储和传输.
内存为了避免处理各种编码统一为unicode码,所以问题就来了,需要进行编码转换.
比如:
gbk转到utf8不能直接转,需要先转到unicode,再转到utf-8
这里要注意str都是unicode编码.
比如 str = "abc"
str.encode("utf-8")
这个操作表现形式上是把str类型转成bytes类型.
实质底层操作是把unicode编码转成了utf-8编码
encode就是由unicode码转为gbk ,utf-8类型的编码
decode 就是由gbk,utf-8类型的编码转成unicode
关于编码总结有以下说明:
bytes的表现形式:
1. 英⽂文 b'alex' 英⽂文的表现形式和字符串串没什什么两样
2. 中⽂文 b'\xe4\xb8\xad' 这是⼀一个汉字的UTF-8的bytes表现形式
字符串串在传输时转化成bytes=> encode(字符集)来完成
记住: 英⽂文编码之后的结果和源字符串串⼀一致. 中⽂文编码之后的结果根据编码的不同. 编码结果
也不同. 我们能看到. ⼀一个中⽂文的UTF-8编码是3个字节. ⼀一个GBK的中⽂文编码是2个字节.