前言时刻

感觉好快呀,不知不觉已经到了第6天,就有一个感觉就是,看视频很爽,但是写总结+代码就累。所以就可以看出一个问题,总结是很有用的。

不说了,现在都快9点了,博客还没写,抓紧写,要睡觉了。

总结总结:

今天学习了代码块、Python 的缓存机制、深浅拷贝。其中深浅拷贝是最重要的。

1、代码缓存机制

Python 的代码缓存机制超级重要,对理解深浅拷贝至关重要。Python 的代码缓存机制一般有两种方式,一种是同一代码块中,另一种是不同代码块中。

同一代码块:指的的是一个模块、一个文件、一个类都可以叫做同一代码块。其缓存指的是所有整数、布尔值、以及几乎全部的字符串,只要值相同,就不在重复创建存储空间。

  1. # 1、同一代码块中
  2. # 字符串
  3. name = "wang"
  4. name2 = "wang"
  5. # 整数
  6. age = 18
  7. age2 = 18
  8. # 布尔
  9. is_study = True
  10. is_study2 = True
  11. print(name is name2) # True
  12. print(age is age2) # True
  13. print(is_study is is_study2) # True

从上面可以看出,所有的int、bool以及几乎所有的字符串都做了缓存优化。除了这三种其他的数据类型均不进行缓存。

不同代码块:一般称之为小数据池,比如你在终端中敲的一行一行的代码,就属于不同代码块。缓存从-5~255的整型、bool、以及满足条件的字符串。

在后面的深浅拷贝,你就会深刻理解缓存机制。

1.1、id 函数

id 是取出存储数据的内存地址号

  1. # 1、id是取出存储数据的内存地址号
  2. age = 18
  3. name = "zhang"
  4. print(id(name)) # 140360327550384
  5. print(id(age)) # 4548361408

1.2 、is 的作用

  1. # 2、is 的作用是判断两者的内存地址是否相同。可以认为是 id
  2. name2 = name
  3. name3 = "zhang"
  4. print(name2 is name) # True
  5. print(name3 is name) # True
  6. print(name3 == name) # True
  7. """
  8. 1、解释下为什么name3和name的存储地址一样呢?
  9. 原因就是Python的缓存机制,在同一代码块下,int 、bool、大部分的str,变量的值相同的话,都是指向同一个存储地址上。说白了就是节省开销。
  10. 而name2和name相同,属于浅拷贝,不难理解,相当于是引用。
  11. 2、== 的作用是?
  12. == 是判断两端的数据是否相同,而is是判断存储数据的地址是否一样(地址一样,数据是必然一样的)。
  13. """

1.4 == 的作用

== 是判断两端的数据值是否相同,而 is 是判断存储数据的存储地址是否一样(地址一样,数据是必然一样的)。

  1. # 2、==
  2. name1 = "tree"
  3. name2 = "tree"
  4. print(name1 == name2) # True

2、深浅拷贝

深浅拷贝的概念很重要,必须要搞懂,否则你会很糊的。尤其是面试的时候,需要手写答案。

2.1、引用型

  1. # 1、“引用” 相当于是重新定义一个变量 但指向同一个列表地址,说白了就是换了个皮。
  2. s1 = [1, 2, [3, 4]]
  3. s2 = s1
  4. s1[-1].append(5)
  5. s2.append(666)
  6. print(s1, s2)
  7. # [1, 2, [3, 4, 5], 666] [1, 2, [3, 4, 5], 666]
  8. # 从结果会发现,s1和s2一毛一样,引用的是同一个内存地址

2.2 、浅拷贝

浅拷贝之后,其成员不创建新的存储空间,和原成员共用一个。

  1. # 2、浅拷贝
  2. import copy
  3. s1 = [1, 2, [3, 4]]
  4. s2 = copy.copy(s1)
  5. s1.append(666)
  6. s2[-1].append(5)
  7. print(s1, s2) # [1, 2, [3, 4, 5], 666] [1, 2, [3, 4, 5]]
  8. # 分析:

1、s2 对 s1 进行了浅拷贝,拷贝的仅仅是各成员的的存储地址(相当于是引用),并未复制一份新的存储空间存放个成员。

所以当对 s1 进行追加 666 时,在 s1 中添加了一个666的存储地址。而 s2 中并没有,所有没有666。

2、s1内部有一个列表(设:l1)变量(属于可变数据类型),当浅拷贝时仅仅是拷贝这个列表的内存地址,并未复制一份新的存储空间存放此列表l1。

所以当对 s2 的最后一个元素进行追加 5 时,s1 和 s2 都指向 l1 地址。

所以当

可以看下面这张图

Python之路day06-深浅拷贝_is_id_==_代码块缓存 - 图1

2.3、深拷贝

成员为不可变数据类型的值,不创建新的存储空间,共用一个。可变的数据类型,复制一份新的,开辟新的存储空间。

说下深拷贝的适用场景,主要用于为了防止复制出来的对象,对原对象造成改变。

  1. import copy
  2. # 深拷贝,没啥好说的,直接复制一份一毛一样的,彼此之间没有影响
  3. s1 = [1, 2, [3, 4]]
  4. s2 = copy.deepcopy(s1)
  5. s1.append(666)
  6. s2[-1].append(5)
  7. print(s1, s2)
  8. # [1, 2, [3, 4], 666] [1, 2, [3, 4, 5]]
  9. # 代码缓存的问题 做题的坑
  10. s1 = [1, 2, [3, 4]]
  11. s2 = copy.deepcopy(s1)
  12. print(s1[0] is s2[0])
  13. print(s1[-1] is s2[-1])
  14. print(s1[-1][0] is s2[-1][0])
  15. # 测测你会答对了几个?
  16. """
  17. True
  18. False
  19. True
  20. """

面试题小试牛刀:


  1. 深度拷贝的题:
    ```python

    代码缓存的问题 做题的坑

s1 = [1, 2, [3, 4]] s2 = copy.deepcopy(s1)

print(s1[0] is s2[0])

print(s1[-1] is s2[-1])

print(s1[-1][0] is s2[-1][0])

测测你会答对了几个?

“”” True False True “””

  1. 2. <br />浅拷贝的题:<br />
  2. ```python
  3. # 2、浅拷贝题
  4. s1 = [1, 2, [3, 4]]
  5. s2 = copy.copy(s1)
  6. print(s1[0] is s2[0])
  7. print(s1[-1] is s2[-1])
  8. print(s1[-1][0] is s2[-1][0])
  9. # 测测你会答对了几个?
  10. """
  11. True
  12. True
  13. True
  14. """

总结:

写了 6 天的项目,才补的 day06 的博客,手动后悔中,明天开始正常看视频+写博客中。另外明天开启一天学两天的课模式,节省时间,要给后面学习 Java 腾时间。

参考文章:

https://www.cnblogs.com/jin-xin/articles/9439483.html