python自学日记32——基础查漏补缺(2)

python自学日记32——基础查漏补缺(2)

跟着各种教程学了很久,发现很多基础的问题被问到还是答不上来,然后决定把基础中漏掉的觉得有用的内容补一下。

首先做个测验:

#1. 思考下面三条语句,他们会改变A打印出的值吗?
A = 'spam'
B = A
B = 'shrubbery'

#2. 思考下面三条语句,他们会改变A打印出的值吗?
A = ['spam']
B = A
B[0] = 'shrubbery'

#3. 这样呢?
A = ['spam']
B = A[:]
B[0] = 'shrubbery'

1.动态类型

python不需要提前声明变量和变量类型,只需要给变量赋值就完成了变量的创建、声明,虽然声明这个概念并不存在python语言中。

举个例子,我们在python中运行赋值语句S=3时,python语言完成了以下三步操作:

1.创建一个对象来代表3;

2.创建一个变量S,如果它还没有被创建的话;

3.将变量与新的对象3相连接。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyUc1Y19-1589810824800)(https://s1.ax1x.com/2020/05/18/YhBCWj.png)]

实际效果如上图所示,在运行S=3后,变量S变成了对象3的一个引用,在内部,变量事实上是到对象内存空间的一个指针。

这个图对于下面一句话的理解很关键

2.类型属于对象,而不是变量

举个例子:

a = 10                   #这是一个整数
a = 'hello world'        #现在它又变成了一个字符串
a = 2.34                 #现在是浮点数

以前我理解的a被赋值10,那么a就是整数类型,按照我以前的理解就是我上面注释的情况,事实上并不是这样,从上面的图可以看出,类型是属于对象而不是变量名,我只是把a先后修改为对不同对象的引用而已(如下图)。实际上,python的变量就是在特定的时间引用了一个特定的对象。

幻灯片2幻灯片3幻灯片4

3.对象的垃圾回收

如同上面图中所写的,我们把变量a赋值给了不同类型的对象,但是当重新给变量a赋值时,它之前引用的对象占用的空间就会被回收(如果它没有被其他的变量名或对象所引用的话)。这种自动回收对象空间的技术叫做垃圾收集。

在内部,python给每个对象添加了一个计数器,记录当前指向该对象的引用变量的数目,一旦(并精确在同一时间)这个计数器被设置为零,这个对象的内存空间就会自动回收。垃圾收集最直接的、可感受到的好处就是,可以在脚本中任意使用对象而不需要考虑释放内存空间,与C和C++等语言相比省去了大量的基础代码。

4.共享引用

举个例子:

a = 10
b = a

这时变量a和b引用的是同一对象10,二者指向的是同一个对象的内存空间。

如果此时修改变量a

a = 20

那么变量a引用了新的对象20,但是b还是引用的是10,这个赋值运算仅仅改变了变量a,变量b并没有发生改变。结合上面图看,给一个变量赋一个新的值,并不是替换了原始的对象,而是让这个变量去引用完全不同的对象。实际的效果就是对一个变量赋值,仅仅会影响那个被赋值的变量。

但是当可变的对象一级远处的改变进入这个场景,那么这个情形会有某种改变。例如

L1 = [1, 2, 3]
L2 = L1

因为L1和L2指向的是同一个可变对象,如果修改了这个可变对象

L1[0] = 5
L1

输出结果:[5, 2, 3]

L2

输出结果:[5, 2, 3]

在这里我们没有改变L1的引用,改变的是引用对象的一个元素,因为L2共享这个引用,所以对L2也产生了影响。

如果不想让L2受影响,可以在给L2赋值为L1引用的副本

L2 = L1[:]

最后再说一个python会缓存并复用小的整数和小的字符串。就像刚开始a=10,后面a又赋值为字符串,这个对象10并不会被立刻回收,它可能仍被保存在一个系统表中,等待下一次变量引用10来重复利用。尽管这样,大多数种类的对象都会在不被引用时马上回收。不过由于缓存机制会影响一些相等问题,如下

X = 10
Y = 10
X == Y  #返回True
X is Y  #如果没有缓存机制,那么会是False,但是返回的是True

都会在不被引用时马上回收。不过由于缓存机制会影响一些相等问题,如下

X = 10
Y = 10
X == Y  #返回True
X is Y  #如果没有缓存机制,那么会是False,但是返回的是True

这个仅仅适用于有缓存的小的整数和小的字符串,如果把10替换为2.3这种浮点数,则返回的是False.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值