VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > python入门教程 >
  • python--高级语法 4

day2:

1、代码块(重点)

  • 代码块:我们所有的代码都需要依赖代码块执行。
  • 一个模块,一个函数,一个类,一个文件等都是一个代码块。。
  • 而作为交互方式输入的每个命令都是一个代码块。

而对于一个文件中的两个函数,也分别是两个不同的代码块:

2、代码块的缓存机制

  1. 两个机制: 同一个代码块下,有一个机制。不同的代码块下,遵循另一个机制。

  2. 同一个代码块下的缓存机制。

    • 前提条件:同一个代码块内。

    • 机制内容:pass

      机制内容:Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。换句话说:执行同一个代码块时,遇到初始化对象的命令时,他会将初始化的这个变量与值存储在一个字典中,在遇到新的变量时,会先在字典中查询记录,如果有同样的记录那么它会重复使用这个字典中的之前的这个值。所以在你给出的例子中,文件执行时(同一个代码块)会把i1、i2两个变量指向同一个对象,满足缓存机制则他们在内存中只存在一个,即:id相同
      
    • 适用的对象: int bool str

    • 具体细则:所有的数字,bool,几乎所有的字符串。

    • 优点:提升性能,节省内存。

  3. 不同代码块下的缓存机制: 小数据池。

    • 前提条件:不同代码块内。

    • 机制内容:pass

      Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。
      
      python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
      
        其实,无论是缓存还是字符串驻留池,都是python做的一个优化,就是将~5-256的整数,和一定规则的字符串,放在一个‘池’(容器,或者字典)中,无论程序中那些变量指向这些范围内的整数或者字符串,那么他直接在这个‘池’中引用,言外之意,就是内存中之创建一个
      
    • 适用的对象: int bool str

    • 具体细则:-5~256数字,bool,满足规则的字符串。

    • 优点:提升性能,节省内存。

总结:

  1. 面试题考。
  2. 回答的时候一定要分清楚:同一个代码块下适用一个缓存机制。不同的代码块下适用另一个缓存机制(小数据池)
  3. 小数据池:数字的范围是-5~256.
  4. 缓存机制的优点:提升性能,节省内存。

3、深浅copy(面试会考)

1,先看赋值运算

  • 对于赋值运算来说,a1与a2指向的是同一个内存地址,所以他们是完全一样的,在举个例子,比如张三李四合租在一起,那么对于客厅来说,他们是公用的,张三可以用,李四也可以用,但是突然有一天张三把客厅的的电视换成投影了,那么李四使用客厅时,想看电视没有了,而是投影了,对吧?a1,a2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表。
#赋值运算
a1=[1,2,3,[22,33]]
a2=a1

a1.append(666)
print(a1,id(a1))
print(a2,id(a2))

[1, 2, 3, [22, 33], 666] 1768812233480
[1, 2, 3, [22, 33], 666] 1768812233480

Process finished with exit code 0

2,浅拷贝copy。

  • 对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。

所以a1 和a2的ID不同,但是内容ID相同

#浅copy

#同一代码块下:
a1=[1,2,3,[22,33]]
a2=a1.copy()

a1.append(666)
print(a1,id(a1))
print(a2,id(a2))

[1, 2, 3, [22, 33], 666] 1321060254472
[1, 2, 3, [22, 33]] 	 1321059431112

Process finished with exit code 0

#*********************************************
# 不同代码块下:
a1=[1,2,3,[22,33]]
a2=a1.copy()

a1[-1].append(666)
print(a1,id(a1))
print(a2,id(a2))
#打印a1 a2中小列表的存储ID
print(id(a1[-1]))
print(id(a2[-1]))

[1, 2, 3, [22, 33, 666]] 2332545303304
[1, 2, 3, [22, 33, 666]] 2332544479944
2332545286088
2332545286088

Process finished with exit code 0

思考1a2 浅拷贝a1后,a1列表中的小列表添加元素后,a2的小列表为啥也添加?

---因为a1 a2  是两个不同的大列表,但是列表里边的元素都是公用一个,所以a1的小列表添加666  a2的小列表也添加666

思考2:如果使a1[0]=90,此时a2[0]是否等于90?  为什么a2[0]不变?
因为之前的a1[0],a1[1],a1[3]是1,2,3  是字符串,是不可变的,我改变的不是a1[0]本身,我只是改变了a1这个列表第一个槽位的内存关系
a1=[1,2,3,[22,33]]
a2=a1.copy()

a1[0]=90
print(a1)
print(a2)

[90, 2, 3, [22, 33]]
[1, 2, 3, [22, 33]]

Process finished with exit code 0

3,深拷贝deepcopy

  • 深copy则会在内存中开辟新空间,将原列表以及列表里边的可变的数据类型重新创建一份,不可变的数据类型则沿用之前的(即公用一个)
#深copy
import copy
a1=[1,2,3,[22,33]]
a2=copy.deepcopy(a1)

print(a1,id(a1))
print(a2,id(a2))

[1, 2, 3, [22, 33]] 1512146813512
[1, 2, 3, [22, 33]] 1512146814664

Process finished with exit code 0

示例:a1[-1].append(666)

#深copy
import copy
a1=[1,2,3,[22,33]]
a2=copy.deepcopy(a1)

a1[-1].append(666)
print(a1)
print(a2)

[1, 2, 3, [22, 33, 666]]
[1, 2, 3, [22, 33]]

Process finished with exit code 0

4,深浅拷贝面试题

#面试题:
# 考察的内容是:切边是深拷贝还是浅拷贝?--浅拷贝
a1=[1,2,3,[22,33]]
a2=a1[:]
a1[-1].append(666)
print(a1)
print(a2)

# 浅copy: list dict: 嵌套的可变的数据类型是同一个。
# 深copy: list dict: 嵌套的可变的数据类型不是同一个 。
def eat(a,b,c,d):
    print('我请你吃:{},{},{},{}'.format(a,b,c,d))

eat('蒸羊羔', '蒸熊掌', '蒸鹿邑','烧花鸭')

# 急需要一种形参,可以接受所有的实参。
# 万能参数: *args, 约定俗称:args,
# 函数定义时,*代表聚合。 他将所有的位置参数聚合成一个元组,赋值给了 args。

def eat(*args):
    print(args)
    print('我请你吃:{},{},{},{}'.format(*args))

eat('蒸羊羔', '蒸熊掌', '蒸鹿邑','烧花鸭')


出处:https://www.cnblogs.com/wushaofan/p/17156647.html

相关教程