【人生苦短,我学 Python】基础篇——变量和引用(Day2)
大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我
热爱AI、热爱编程、热爱分享
! 这博客是我对学习的一点总结与思考。如果您也对深度学习、机器视觉、算法、Python、C++
感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github
前言:
本专栏在保证内容完整性的基础上,力求简洁,旨在让初学者更快地入门Python。这个Python学习专栏我打算分三个阶段:基础知识、进阶知识、实战训练。这将是一套完整、高效、循序渐进的Python系列讲解,您可以当做Python学习的入门教程。
一、初识变量
1.1 程序如何执行
在上一篇文章中,我们学会了如何运行第一个程序。那么在运行程序时, Python 都做了些什么呢?下面来深入研究一下。实际上,即便是运行简单的程序, Python 所做的工作也相当多:
print("人生苦短,我学Python!")
- 1
运行上述代码时,你将看到如下输出:
人生苦短,我学Python!
- 1
其实,当我们开始运行程序时,编辑器将使用 Python 解释器 来运行它。 Python 解释器读取整个程序,确定其中每个单词的含义。例如,看到单词 print 时,解释器就会将括号中的内容打印到屏幕,而不会管括号中的内容是什么。
1.2 尝试使用第一个变量
下面来尝试在上述程序中使用一个变量。在上面程序开头添加一行代码,并对第 2 行代码进行修改,如下所示:
title = "人生苦短,我学Python!"
print(title)
- 1
- 2
运行这个程序,你会发现,输出与上面相同:
人生苦短,我学Python!
- 1
实际上,我们添加了一个名为 title 的变量 。每个变量都存储了一个值 。在这里,存储的值为文本 “人生苦短,我学Python!” 。
添加变量导致 Python 解释器需要做更多工作。处理第 1 行代码时,它将文本 “人生苦短,我学Python!” 存储到变量 title 中 ;而处理第 2 行代码时,它将与变量 title 打印到屏幕。
二、变量的命名规则
变量不是随便命名的,它的命名规则如下:
- 变量名必须是字母或者_开头,比如title、title66、_title等;
- 变量名的其他部分可以是字母、_ 或者数字;
- 变量名不能是关键字,比如for、import之类的。
除此之外,还需要注意的是:Python中变量名大小写是区分的,title和Title表示不同的变量。
其中,以下划线_开头的标识符(变量)是有特殊意义的,具体如下:
- 以单下划线_开头的代表不能用
from xxx import *
导入,比如 _module - 以双下划线开头的代表类的私有成员,比如 __member
- 以双下划线开头和结尾的代表python里特殊方法专用的标识,比如__init__()代表类的构造函数,供解释器使用。
三、变量的赋值
3.1 赋值过程
和C/C++不一样的是,在Python中变量是不需要声明的。变量通过首次赋值产生,当超出作用范围时自动消亡。
那么X=1,该赋值在Python中是如何进行的呢?
Pytho中变量的赋值与C/C++有很大不同,其过程如下:
- 在内存中创建对象1
- 创建变量名X
- 把变量和对象建立映射关系
在赋值时,是把对象的引用而不是值赋值给变量。变量可以引用任何类型的对象。变量没有类型,只有对象有类型。而且变量在使用前必须被赋值。
3.2 一次赋多值
在Python中可以一次赋多值,比如:
上述过程,一次性对七个变量赋值,分别赋值为0、1、…、6
3.3 多重赋值
在Python中也可以多重赋值,比如:
上述过程,同时将x,y,z赋值为1。
3.4 交换变量的值
在C/C++中交换两个变量的值时,通常需要建立一个中间变量,如下所示:
int a = 7;
int b = 8;
int temp;
temp = a;
a = b;
b = temp;
- 1
- 2
- 3
- 4
- 5
- 6
在Python中,语法更为简单,可以轻松交换两个变量a、b的值。具体做法如下:
a = 7
b = 8
a,b = b,a
- 1
- 2
- 3
对比C/C++,可以发现Python的语法更为简捷!
注:对于初学者可先了解变量部分即可,下文暂时可不要求掌握,不会影响后面专栏的学习。
四、对引用的理解
4.1 理解引用
在前面赋值过程中,多次提到了引用。那么在Python中,应该去如何理解引用呢?
Python把一块数据存储在对象中,变量是对象的唯一引用;它们是计算机内存中特殊地点的名字。所有对象都具有唯一的ID号、类型和值。对象的类型不会改变,对于可变类型而言,它的值是可变的。
id(对象)函数可用于检索对象的ID,也就是内存中的对象的地址。
每一个对象都包含引用计算器,它记录当前有多少个变量正在引用该对象。当给对象指定一个变量,或使对象成为列表或其他包容器的成员时,引用计数增加。
当从包容器中撤销、重新分配或删除对象时,引用计数减少。当引用计数达到0值时,这时没有任何变量引用这个对象,Python的回收机制会自动回收它使用的内存。
注意:del可以用来删除变量,但是不能删除对象。sys.getrefcount(obj)函数可返回给定对象的引用计数。
下面,我们来看一个简单的例子:
通过赋值语句:a=1,在对象1和变量a之间通过引用建立联系。
通过内置函数:sys.getrefcount(1),可知有1565个变量在引用对象。
通过删除操作:del a,可知del删除的是变量,而不是对象1本身。
再执行:del a ,报错,是因为变量a已经被删除。
4.2 del和垃圾回收
下面举一个简单的例子:
分析:del删除变量,而不是对象。在删除变量a之后,未经初始化就不能使用它,所以出现图示红色报错。需要注意的是:虽然a被删除了,但是b仍然有效,这是因为b指向的对象还在。
Python的垃圾回收:自动垃圾回收,这是Python的一个特点。主要依靠的算法是引用计数,当引用计数归零时,对象立即被销毁。也就是说,当 del 删除了对象最后一个引用的时候,对象才会被自动销毁。
4.3 浅拷贝和深拷贝
通过给列表分配一个变量能创建对列表的引用,如果要创建列表的副本就要理解浅副本和深副本的概念。
- 列表或其他容器对象的浅拷贝生成对象本身的拷贝,并将其包含的对象插入到新对象中。可用分片(object[:])和 copy模块的copy(obj)函数创建。
- 列表或其他对象容器的深拷贝生成对象本身的副本,并递归地生成所有子对象的拷贝,加入到新对象中。可用copy模块的deepcopy(obj)函数创建。
比较两种拷贝的副本,一般情况下表现是一样的。但是当列表内包含另一个列表的情况下,父列表的浅副本将包含对子列表引用,而不是独立副本。其结果是,当更改其内部列表时,从父列表的两个副本中都可见,如下两个例子:
(1) 通过切片操作符,或者copy.copy()进行浅拷贝
通过上面例子,可知:
- 通过id,我们可以知道,变量a、b是指向向相同的列表对象。
- c通过切片a[:]复制列表,生成新的列表对象。
- 对原始列表进行修改,切片生成的队列也被修改
(2) 通过copy.deepcopy()函数进行深拷贝
从上面里可以看出:
- 进行深拷贝前,要先导入copy模块
- 调用deepcopy从a生成b,从id可以看出,两个列表为不同的对象
- 对a进行修改,b保持不变
五、要点总结
- Python是解释型语言,编辑器会使用 Python 解释器 来运行程序。
- 以下划线_开头的标识符(变量)是有特殊意义,不能随便命名并使用。
- 在Python中变量不需要声明,变量在使用前必须被赋值。
- 在赋值时,是把对象的引用而不是值赋给变量。
- del可以用来删除变量,但是不能删除对象。
- 通过切片操作符,或者copy.copy()进行浅拷贝;通过copy.deepcopy()函数进行深拷贝。
- 在高级语言中,变量是对内存及其地址的抽象。对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身。
- Python一切皆对象。
文章来源: ai-wx.blog.csdn.net,作者:AI 菌,版权归原作者所有,如需转载,请联系作者。
原文链接:ai-wx.blog.csdn.net/article/details/111190979
- 点赞
- 收藏
- 关注作者
评论(0)