6.小数据池,编码问题

1. 小数据池

id

id() 查看变量的内存地址

通过id()我们可以查看到一个变量表示的值在内存中的地址

小数据池针对的是: int, str, bool
在py文件中几乎所有的字符串都会缓存.

a = 10
b = 30
print(id(a))#1352229376
print(id(b))#1352230016

lst = ["胡辣汤"]
print(id(lst))#3070023188872
lst = []
lst.append("胡辣汤")
print(id(lst))#3070023188808

lst1 = [1,2,3]# 两个对象 内存地址是不一样的
lst2 = [1,2,3]
print(id(lst1))#2114848899464
print(id(lst2))#2114848899272

s1 = "abc" #内存中没有"abc",创建一个新的0.0001
s2 = "abc" #内存以有力"abc" 直接拿"abc" 0.00000001
print(id(s1),id(s2))#2447874555384 2447874555384

# 把字符串的缓存-> 小数据池 -> String iterning -> 常量池 -> 字符串缓存

#什么数据会缓存
#数字,字符串,布尔值 ==>不可变的数据类型

#字符串.如一连串字符串,几乎都会被缓存
s1 = "alex昨天上厕所没关门. 韩红冲进去了. 面筋歌出来了"
s2 = "alex昨天上厕所没关门. 韩红冲进去了. 面筋歌出来了"
print(id(s1),id(s2))#2431087496432 2431087496432
# 如果在py文件中写的字符串. 几乎都是缓存的
# 在黑窗口里的写的几乎都不会缓存
# 不同的解释器. 缓存的机制也不一样
# 优点: 可以帮我们快速的创建对象.节省内存.
# 缺点: 缓存如果过大. 响应速度会比较慢

 is和==的区别

     is 判断左右两端内容的内存地址是否一致,如果返回True,哪么可以确定这两个变量使用的是同一个对象
     == 判断左右两端的值是否相等,是否一致
当两个变量指向同一个对象的时候. is是True, ==也是True

lst1 = [1,2,3]
lst2 = [1,2,3]
print(id(lst1),id(lst2))#1634021425544 1634021425480
print(lst1==lst2)#Ture
print(lst1 is lst2)#False

s1 = "我是小钱"
s2 = "我是小钱"
print(id(s1),id(s2))#1603830872352 1603830872352
print(s1==s2)#True
print(s1 is s2)#True

  我们可以这样认为. 如果内存地址相同. 那么值一定是相等的. 如果值相等. 则不一定是同一个对象

小数据池

     一种数据缓存机制. 也被称为驻留机制. 各大编程语言中都有类似的东西. 在网上 搜索常量池,小数据池指的都是同一个内容. 小数据池只针对: 整数, 字符串, 布尔值. 其他的数据类型不存在驻留留机制.

在python中对-5到256之间的整数会被驻留在内存中. 将一定规则的字符串缓存. 在使用 的时候, 内存中只会创建一个该数据的对象. 保存在小数据池中. 当使用的时候直接从小数据 池中获取对象的内存用. 而不需要创建一个新的数据. 这样会节省更多的内存区域.

优点: 能够提高一些字符串, 整数的处理速度. 省略的创建对象的过程.

缺点: 在'池'中创建或者插入新的内容会花费更多的时间. 对于数字: -5~256是会被加到小数据池中的. 每次使用都是同一个对象. 对于字符串:

  1. 如果字符串的长度是0或者1, 都会默认进行缓存
  2.  字符串长度大于1, 但是字符串中只包含字母, 数字, 下划线时才会缓存
  3. 用乘法的到的字符串.

    ①. 乘数为1, 仅包含数字, 字母, 下划线时会被缓存. 如果 包含其他字符, 而长度<=1 也会被驻存,

    ②. 乘数大于1 . 仅包含数字, 字母, 下划 线这个时候会被缓存. 但字符串长度不能大于20

       4. 指定驻留. 我们可以通过sys模块中的intern()函数来指定要驻留的内容.
OK. 到目前为止. 我们已经了解了python的小数据池的一些基本情况了. 但是 还有最后一 个问题. 小数据池和最开始的代码块有什么关系呢? 同样的一段代码在命令行窗口和在py文件中. 出现的效果是完全不一样的.

a = 1000
b = 1000
print(a is b)
注意. 在py文件中.得到的结果是True, 但是在command中就不是了.
 

         在代码块内的缓存机制是不一样的. 在执行同一个代码块的初始化对象的命令时, 会检 查是否其值是否已经存在, 如果存在, 会将其重用. 换句话说: 执行同一个代码块时, 遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中, 在遇到新的变量时, 会先在字典中查询记录, 如果有同样的记录那么它会重复使用这个字典中的之前的这个值. 所以在你给出的例子中, 文件执行时(同一个代码块) 会把a, b两个变量指向同一个对象. 

       如果是不同的代码块, 他就会看这个两个变量是否是满足小数据池的数据, 如果是满足小数据池的数据则会指向同一个地址. 所以: a, b的赋值语句句分别被当作两个代码块执行, 但是他们不满足小数据池的数据所以会得到两个不同的对象, 因而is判断返回False.   

 编码的补充 

在python3中. 默认的编码是unicode,我们的字符串就是unicode
在python2中. 默认的编码是ASCII. Cpython.c语言的默认编码是ASCII需要在文件开头写

# -*- encoding:utf-8 -*

unicode弊端:在存储和传输的时候. 是很浪费的
在存储和传输的时候不能直接使用unicode. 必须要对字符串进行编码. 编码成bytes类型

编码回顾

1.ASCll:最早的编码,里面有英文大小写,小写字母,数字,一些特殊字符,没有中文

8个01代码,8个bit,1个byte

GBK:中文国编码,里面包含了ASCll码和中文编码16个bit ,2个byte

UNCODE:万国码,里面包含了世界所有国家文字的编码,32个bit,4个byte包含ASCll

UTF-8:可变长度的万国码,是unicode是一种实现,最小字符占8位

   1.英文:8bit 1byte

   2.欧洲文字:16bit 2byte

   3.中文:24bit 3byte

综上,除了ASCll码以外,其他信息不能直接转换

在python3的内存中. 在程序运行阶段. 使用的是unicode编码. 因为unicode是万国码. 什么内容都可以进行显示. 那么在数据传输和存储的时候由于unicode比较浪费空间和资源. 需要把 unicode转存成UTF-8或者GBK进行存储. 怎么转换呢. 在python中可以把⽂字信息进行编码. 编码之后的内容就可以进行传输了了. 编码之后的数据是bytes类型的数据.其实啊. 还是原来的数据只是经过编码之后表现形式发生了改变而已. 

bytes: 字节形式的字符串

     1. 英文 b'alex' 英⽂文的表现形式和字符串没什么两样

      2. 中文 b'\xe4\xb8\xad' 这是一个汉字的UTF-8的bytes表现形式

1. encode(编码格式) 编码

2. decode(编码格式) 解码

bs = b'\xe6\x88\x91\xe4\xbb\x8a\xe5\xa4\xa9\xe9\x9d\x9e\xe5\xb8\xb8\xe7\x9a\x84\xe5\x9b\xb0'
# 把这个bytes转化成gbk的bytes
s = bs.decode("utf-8")
g = s.encode("gbk")
print(g)

记住: 英文编码之后的结果和源字符串一致.  中文编码之后的结果根据编码的不同. 编码结果也不同. 我们能看到. 一个中文的UTF-8编码是3个字节. 一个GBK的中文编码是2个字节. 编码之后的类型就是bytes类型.  在网络传输和存储的时候我们python是保存和存储的bytes 类型. 那么在对方接收的时候. 也是接收的bytes类型的数据. 我们可以使用decode()来进行解码操作. 把bytes类型的数据还原回我们熟悉的字符串

一. 上节课内容回顾
    1. 字典
        {key:value, key:value.....}
        成对的保存数据

        字典没有索引. 不能切片, 字典的key必须是可哈希的.不可变的
        1. 增加:
            dic[新key] = 值
            dic.setdefault(key, value) 新增, 查询
        2. 修改:
            dic[老key] = 值
            dic.update(d) 把d更新到dic中
        3. 删除;
            pop(key)
            popitem() 随机删除
            del dic[key]
            clear() 清空
        4. 查询
            for k in dic:
                k
                dic[k]

            get(key) 如果key不存在, 返回None
            dic[key] 如果key不存在, 报错

            setdefault(key, value)
            根据key查询出value
        5. 相关操作
            1. keys()     所有的key
            2. values()     所有的value
            3. items()      所有的key和value
            for k, v in dic.items(): # 自动解包
                k
                v
    set集合
        内部元素必须可哈希. 不可变
        内部元素不重复

        add() 添加

        frozenset() 冻结集合. 不可变的.

二. 作业

三. 今日主要内容
        1. 小数据池, id()
            小数据池针对的是: int, str, bool
            在py文件中几乎所有的字符串都会缓存.
            id() 查看变量的内存地址
        2. is和==的区别
            is 比较的是内存地址
            == 比较的是内容
            当两个变量指向同一个对象的时候. is是True, ==也是True

        3. 再谈编码
            回顾:
                1. ascii. 有: 数字, 字母, 特殊字符. 8bit  1byte 128  最前面是0
                2. gbk. 包含: ascii, 中文(主要), 日文, 韩文, 繁体文字. 16bit, 2byte.
                3. unicode. 包含gbk,ascii,big5... 32bit, 4byte
                4. utf-8. 可变长度的unicode.
                    1. 英文: 8bit,1byte
                    2. 欧洲文字: 16bit 2byte
                    3. 中文: 24bit 3byte
            不同的编码之间不能随意转换. 中国人gbk和德国人utf-8骂 想要沟通必须通过英文(unicode)(媒介)

            在python3中. 默认的编码是unicode,我们的字符串就是unicode
            在python2中. 默认的编码是ASCII.  Cpython.c语言的默认编码是ASCII

            unicode弊端:在存储和传输的时候. 是很浪费的
            在存储和传输的时候不能直接使用unicode. 必须要对字符串进行编码. 编码成bytes类型
            bytes: 字节形式的字符串

                1. encode(编码格式) 编码
                2. decode(编码格式) 解码

            bytes是一种另类的字符串表示形式
            "哈哈哈" => \xee\xab\x13\xee\xab\x13\xee\xab\x13

        预习:
            深浅拷贝(难)
            基本数据类型的知识点补充(join)
            关于字典和列表的删除

            周末作业(zip, day5)
            质数
            数字的长度
大概内容

 

作业

6.列表字典作业

posted @ 2019-02-24 14:20  等待の喵  阅读(357)  评论(0编辑  收藏  举报