程序的构成
- python程序由模块组成,一个模块对应一个python源文件,后缀为.py
- 模块由语句组成,运行python程序时,按照模块中的语句顺序依次执行
- 语句是python程序的构造单元,用于创建对象,变量赋值,调用函数,控制语句等
对象的基本组成
python中,一切皆为对象,对象由三部分组成: 标志,类型,值
- 标志一般对应计算机内存地址,可以使用内置函数id 返回对象obj的标识
- 类型限制对象的取值范围以及可执行的操作,可以使用type获得对象的所属类型
- 值则为对象存储数据的信息,直接使用print打印输出
所以,对象其实就是一个内存块,然后拥有特定的值,支持特定类型的相关操作
标识符
简单理解,标识符其实就是名字,就好像我们每个人也都有自己的名字一样,它的主要作用是作为变量、函数、类、模块以及其他对象的名称
python中的标识符的命名并不是随意的,需要遵守一定的命名规则:
- 标识符需要由字母、下划线以及数字组成,且第一个字符不能是数字
- 标识符不能和python中的保留字相同,保留字可以通过以下代码查看:
import keyword
print(keyword.kwlist)
- 标识符不能包含各种特殊字符,比如说空格 百分号等等
- 标识符中的字母是区分大小写的,这个一定要注意
- python中以下划线开头的标识符通常有特殊含义,譬如类属性、类的私有成员、专有标识符等
- 标识符的命名,除了要遵守以上这几条规则外,不同场景中的标识符,其名称也有一定的规范可循,例如:
- 当标识符用作模块名时,应尽量短小,并且全部使用小写字母,可以使用下划线分割多个字母,例如 game_mian、game_register 等
- 当标识符用作包的名称时,应尽量短小,也全部使用小写字母,不推荐使用下划线,例如 com.mr、com.mr.book 等
- 当标识符用作类名时,应采用单词首字母大写的形式。例如,定义一个图书类,可以命名为 Book,模块内部的类名,可以采用 “下划线+首字母大写” 的形式,如 _Book
- 函数名、类中的属性名和方法名,应全部使用小写字母,多个单词之间可以用下划线分割;常量命名应全部使用大写字母,单词之间可以用下划线分割
变量
因为python中不需要声明变量类型,所以使用变量之前直接进行赋值,然后变量就会被创建,使用=对变量进行赋值,左侧为变量名,右侧为存储在变量中的值
变量类型
数字
- int 有符号整型
- float 浮点型
- long 长整型,也可以代表八进制和十六进制
- complex 复数
字符串
数字、字母、下划线组成的一串字符,用单引号或者双引号进行标识
元组
tuple使用()标识
列表
list使用[]标识
字典
dict使用{}标识
布尔
True / False
垃圾回收机制
主要需要了解三个方面
引用计数
每个对象维护一个ob_ref,用来记录当前对象被引用的次数,也就是来追踪到底有多少引用指向这个对象,说明白点:
- 对象被创建 +1
- 对象被引用 +1
- 对象被作为参数传入函数 +1
- 对象作为元素被存储进容器 +1
- 对象别名被显示销毁 也就是使用del函数 -1
- 对象的引别名被赋予新的对象 -1
- 元素从容器被删除或者容器被销毁 -1
- 对象离开作用域,譬如函数执行完毕之后函数里面的局部变量 -1
而当指向该对象的内存的引用计数器为0的时候,该内存被python虚拟机销毁
引用计数法优缺点也很明显
优点:
- 高效
- 实时性,一旦没有引用,内存就直接释放了,不需要等到特定的时机,而且回收内存的时间也被分摊到了平时
- 对象有确定的生命周期
- 易于实现
缺点: - 维护引用计数消耗资源,维护引用计数的次数和引用赋值成正比,而不像mark and sweep等基本与回收的内存数量有关
- 无法解决循环引用的问题。A和B相互引用而再没有外部引用A与B中的任何一个,它们的引用计数都为1,但显然应该被回收。
也正是因为引用计数的缺点,对于循环引用的情况,或许代码内部有一组未使用的、互相指向的对象,但是谁都没有外部引用,但是因为引用计数都是1而不是0,所以不可能由python的垃圾回收机制去释放这些对象并且回收它们占用的内存空间,也因此python引入了两种GC机制
标记-清除
标记清除算法是一种基于追踪回收技术实现的垃圾回收算法。
它分为两个阶段,首先是标记阶段,GC会把所有的活动对象打上标记,然后是把那些没有标记的对象也就是非活动对象进行回收。
而GC判断活动对象和非活动对象的方法为:
对象之间通过引用(指针)连在一起,构成一个有向图,如下图所示,对象为节点,引用关系则为线。从根对象出发,沿着有向边遍历对象,可达的对象标记为活动对象,不可达的对象就是要被清除的非活动对象。
根对象就是全局变量、调用栈、寄存器。
上图中,我们从小圆圈,也就是全局变量开始,可以直达或者间接到达的是对象1、2、3,而4、5不可达,因为4、5将作为非活动对象而被GC回收
标记清除算法作为python的辅助垃圾收集技术,主要处理一些容器对象,例如列表,字典,元组等等
不过这种简单粗暴的标记清除算法也有明显的缺点,毕竟它需要顺序扫描整个堆内存