对存储空间的申请和存储空间的释放的操作
数据值被谁使用过,如果引用计数为0的时候说明数据值不被再使用了,可以被垃圾回收机制回收,如果计数引用不是0说明还有被在用,不会被垃圾回收机制处理
# 循环引用 l1 = ['jason', ] l2 = ['kevin', ] l1.append(l2) # 引用计数为2 l2.append(l1) # 引用计数为2 del l1 # 解除变量名l1与列表的绑定关系 列表引用计数减一 del l2 # 解除变量名l1与列表的绑定关系 列表引用计数减一
循环引用的原理是,俩个数据互相循环利用彼此之间。标志清除是专门用来解决这种事情,每隔一段时间将程序中的数据值检查一遍,查看是否存在这种数据值标记好最后一次性清除
由于标记清除需要每隔一段时间就得去检查一遍,过于消耗资源,因此又出现了分代回收
通过检查标记,将使用频率次数过高的放入下一代,然后分代管理,间隔时间不同,节约资源的消耗,越往下检测的间隔时间越长
计算机只能识别0和1,但是我们使用计算机由于各国的语言不同,我们的语言需要与数字需要进行转换,于是就出现了字符编码表,它记录了字符与数字之间如何转换
(内存使用unicode 硬盘使用utf8)
乱码问题:接收到的文件是以什么编码写的就以什么去解码
编码与解码:
编码是将人类的字符通过编码转换为计算机能认识的数字
编码是将计算机的数字通过编码转换为人类能认识的字符
解释器:
python2解释器要utf8出现的早,它默认的是ASCLL码,在使用的时候需要在文件的头部加上''coding:utf8'',在字符串前面加上''u''
python3解释器默认的是utf8
通过编码写代码自动读写文件
双击文件图标是从硬盘加载数据到内存
保存文件就是将内存中的数据刷到硬盘
文件就是操作系统暴露给用户操作计算机硬盘的快捷方式之一
方式一:open(文件路劲,读写模式,字符编码)
方式二:with open() as 变量名:
子代码运行结束后自动调用close()方法
ps: with模式支持打开多个文件
可能存在特殊含义,可以通过在文件路径前面加上r
r----文件只能进行读的操作模式
当文件路径不存在的时候,会报错
当文件路径存在的时候,读取内容
w----文件只能进行写的操作模式
当文件路径不存在的时候,创建文件,然后写入内容
当文件路径存在的时候,清空文件内容,然后写入内容
a----文件进行追加模式
当文件路径不存在的时候,创建文件写入内容
当文件路径存在的时候,打开文件不会清空内容,在文件的末尾追加写入内容
t----文本模式(默认模式)
只支持文本类型,必须指定encoding参数,以字符为单位
b----二进制模式
支持图片、音频等类型,不需要指定encoding参数,以bytes为单位
文件数据过于打的时候,可以结合使用for循环,循环一次只读一行
.read() 一次性读取完所有文件,光标移动到文件的末尾,如果还进行读取操作的话,将不会在读取到内容
.readline() 每次只读取一行内容
.readlines() 一次可以读取到多行内容,组织成列表返回
.readable() 是否可读取内容
.writable() 是否可以进行读写内容
.writlines() 支持填写容器类型,内部可以放入好多数据内容,例如列表、字典
.flush() 将内存中的数据立即刷到硬盘上 然后按ctrl+s
with open(r'aaa.txt', 'r', encoding='utf8') as f: data = f.read(3) print(data)
8.1.文本模式下read括号内的数字表示的是数字表示读取几个字符
二进制模式下必须写上t,read括号内的数字表示的是读取几个字节
8.2.光标的控制移动
.seek(offset(光标移动的字节数,whence(模式控制)))
0 模式 ---基于文件开头向后移动多少个字节,t、b模式都可以使用
1 模式---基于文件当前位置移动多少个字节,只能在b模式下使用
2 模式---基于文件末尾位置移动多少个字节,只能在b模式下使用
9.1.机械硬盘存储数据原理:
数据的修改、数据的删除
9.2.修改代码文件的方式
方式一:覆盖写
先读取文件内容到内存,在内存中完成修改,之后w模式打开该文件写入
方式二:重命名
先读取文件内容到内存,在内存中完成修改,之后保存到另一个文件中,再将原来的文件删除掉,将新文件重新命名为原来文件的名称
优点是不会造成内存溢出,缺点是有一段时间可能需要占有硬盘俩个地方的空间,可能是在内存中创建还没有刷到硬盘中去
函数可以看作是工具,提前先定义好,之后可以直接拿来使用,并且是可以反复重复的使用
def 函数名(参数1,参数2....): '''函数功能的注释''' 函数体(实现功能的代码) return 返回值
函数在使用之前必须先定义才可以使用,定义的函数必须要在调用的函数之前先执行
函数的调用规则是使用函数名加括号,括号必须写,里面可传参数也可以不传
函数在定义阶段只检测函数体的代码语法,只要语法上遵循规则就不会报错,不会执行函数体
函数名其实是一个内存地址,里面存放着函数体代码,我们在使用的时候在后面给它加上括号就可以使用,函数名加括号执行的优先级最高,它与变量名不同的是变量名绑定的是一个具体的值,而函数名绑定的是一串代码,想执行这串代码的话就调用它
4.1.内置函数
解释器提前定义好的函数,用户可以直接调用
内置函数与内置方法的区别是,内置函数可以使用在任何地方而内置方法必须跟在具体的数据类型之后
4.2.自定义函数
空函数:没有函数体没有参数,用于搭建主体,后期通过功能的需求然后进行代码功能的完善
无参函数:首先空函数也算是无参函数的一种,无参函数就是在使用的时候无需传入参数直接函数名加括号就好了
有参函数:在定义的时候加入需要的参数,在函数调用的时候需要传入对应的参数进行使用,不给参数会报错
返回值就是函数在调用执行完函数体的时候产生的结果,看你需要的结果的值是什么,进行设置,可以有也可以没有,没有的话默认返回的是None
函数返回值得情况:
1.函数体代码没有return---返回的是None
2.函数体代码有关键字return 没有返回的值---返回的还是None
3.函数体代码有return并且有值---那么就返回这个值的结果(如果是数据值的话就返回数据值,如果是变量名的话就返回变量名绑定的值等,反正就是是什么就返回什么)
4.函数体代码有return并且后面写了多个数据值用逗号隔开---它默认情况下返回的是元组,如果想要返回其他的类型就要自己加上他们该有的特征
5.函数体代码遇到return关键字就会立即结束函数体的执行,如果下面还有执行语句是不会执行的,类似于循环里的break
形式参数:出现在的是函数定义阶段,括号内写的,可以不写,也可以写多个。
实际参数:出现在的是函数调用阶段,如果需要传参数进去的话就需要写,根据定义阶段形式参数的情况而定。
他们俩之间的关系就是,形式参数相当于变量名,实际参数相当于的是数据值,但是只是在函数调用阶段形参会临时与实参进行绑定,在函数运行结束立即解除,动态绑定,动态解除
位置形式参数:在函数定义阶段括号内从左往右依次填写的变量名称之为位置形参
位置实际参数:在函数调用阶段括号内从左往右依次填写的变量名称之为位置实参
需要注意的是形参与实数的个数要一致,实参传的多了也不行少也不行
需要使用在函数调用阶段从实参传给形参的时候,写法通常是什么等于什么,也就是指名道姓的传值
需要注意的是,同一个形参不能在同一次调用执行的时候给予多个实参数据,位置参数不能放在关键字参数后面
小技巧:也可以记为,无论是形参还是实参,越短得越靠前(这个长短不是长短得长短,而是它们得复杂程度)
def func(a, b): print(a, b) func(b=1, 2) # positional argument follows keyword argument # 此时的情况就是关键字实参与位置参数都要给位置形参b传值,结果就会报错
关键字参数主要针对的是实参,默认值参数主要针对的是形参
主要用于函数定义的阶段,就定义函数的时候就默认给予参数初始值,如果后期需要别的值也可以传入,这个时候参数的默认值将不再是原来的默认值会更改为现在你传入的值
打破了形参与实参的个数限制,随意传值
君子协议:*
args,*
kwargs
*
args---在形参中使用,接收多余的位置参数,然后组织成元组的形式赋值给*
后面的变量名
*
kwargs---在形参中使用,接收多余的关键字参数,然后组织成字典的形式赋值给**
后面的变量名
def func(*X, **Y): print(X) print(Y) func() # () {} 没有位置形参也没有关键字形参,返回一个空括号,返回一个空字典 func(1) # (1,) {} 没有位置形参也没有关键字形参,但是1是位置实参,所以放到了多余的位置形参里,没有多余的关键字形参,返回一个空字典 func(1, 2) # (1, 2) {} 没有位置形参也没有关键字形参,但是1,2是位置实参,所以放到了多余的位置形参里,以元组的方式返回,没有多余的关键字形参,返回一个空字典 func(a=1) # () {'a': 1} 没有位置形参也没有关键字形参,没有多余的位置实参,返回一个空括号,a=1是多余的关键字实参,所以放到多余的关键字形参里 func(a=1, b=2) # () {'a': 1, 'b': 2} 没有位置形参也没有关键字形参,没有多余的位置实参,返回一个空括号,a=1,b=2是多余的关键字实参,所以放到多余的关键字形参里