文件处理和函数基础
开始
计算机使用具备哪几部分
- 计算机硬件
- 操作系统
- 软件
计算机软件的最终目的
我们使用软件的时候,操作系统已经封装好了接口,我们可以通过调用操作系统封装好的接口,实现对计算机的硬件操作。
文件处理
通常我们对文件的处理可分为三步
- 打开
- 读/写
- 关闭
在Python中我们是如何操作文件的呢
open("文件路径",mode="操作方式",encoding="utf-8")
首先我们先分析一下他的流程:
- 1:向操作系统发起操作系统调用
- 2:操作系统打开这个文件,返会一个文件句柄给相应程序
- 3: 在应用程序中把文件句柄赋值给一个变量
例子:
f = open("a.txt",mode="r",encoding="utf-8")
f.read()
f.close()
这里需要注意的事:字符编码。因为windows系统打开文件用gbk编码方式打开文件。如果不知指定字符编码读取的时候要出问题的
f = open("a.txt",mode="r",encoding="utf-8")这里是赋值一个变量给f,差别它所赋值的是应用程序的文件句柄
f.read()操作系统给了我们一个文件句柄f,我们通过这个文件句柄
对操作系统发起read等操作f这个文件句柄的调用。
那么f对应两个两部分内容:
- 一个是应用程序
- 另一个是操作系统
f.close()这个是关闭文件。为什么要关闭文件呢,而核心在于文件对应的应用程序拿一个资源,操作系统拿一个资源。
因为Python的处理机制,所以我们不用关心应用程序的资源,我们要把重点放到系统所拿的资源上。
当我们把文件关闭后,我们在f.read()的时候它会报一个错ValueError: I/O operation on closed file.
这个文件句柄已经关闭,不能被操作系统接收了。如果打开文件不执行f.close()在操作系统还存在这个打开的存在,虽然
虽然操作系统会自动清理掉,但是需要时间。如果在高并发的场景会很麻烦。如果直接del f 这里是回收的
Python的资源,而不是操作系统的资源。
打开文件的方式
在Python中有两种打开文件的方式
- f = open("文件路径",mode="打开方式",encoding="字符集")
- with open("文件路径",mode="打开方式",encoding="字符集") as f:
这两种方式的区别
它们的区别在于前者需要手动关闭打开的这个文件,而后者使用with语句(一种语法糖,语法糖语句通常是为了简化某些操作而设计的)。with语句会在其代码块执行完毕之后自动关闭文件。
f = open("a.txt",mode="r",encoding="utf-8")
f.read()
f.close()
print(f.closed) #验证文件是否关闭
True
with open("a.txt",mode="r",encoding="utf-8") as f:
f.read()
print(f.closed)
True
我们发现with这种方式不需要关闭文件它会根据代码的缩进自动关闭
打开文件的模式
我们经常用到的这几个
- r ,只读模式(如果不加打开文件方式,默认是只读模式)
- w ,只写模式(不可读,当文件不存在时候,它会创建。用这个模式要慎重,因为它会把原来的内容覆盖)
- a ,追加模式(不可读;不存在的创建,存在的追加)
对于非文本格式我们可以用b模式。"b"表示以字节方式打开。因为在硬盘中所有的文件丢失
以字节方式存储,并不局限于文本文件,它还可以是图片和视频等。- rb
- wb
- ab
这里需要注意以b的方式打开的时候,读取到的内容是字节,写入也要是字节,不能指定编码
操作文件的方法
在读模式"r"下对文件的操作
- f.read() #读取所有内容,光标移动到末尾
- f.readline() #一行一行的读,每次只读取一行。
- f.readlines() #以列表的方式读取,每次读取一行
在写模式"w"下对文件的操作
- f.write() #针对文本模式的写,需要自己填写换行符"\n"
- f.write("内容".encode("utf-8")) #针对b模式的写的时候也要有换行符,字符集
- f.writelines(['tom\n','bob\n']) #文件模式
- f.writelines([bytes('tom\n',encoding='utf-8'),'bob\n'.encode('utf-8')]) #b模式
检测文件- f.readable() #文件是否可读
- f.writable() #文件是否可读
- f.closed #文件是否关闭
- f.encoding #如果文件打开模式为b,则没有该属性
- f.flush() #立刻将文件内容从内存刷到硬盘
- f.name
函数基础
函数的优点
- 1、组织结构简单,可读性高
- 2、代码无冗余
- 3、可以统一管理,维护难度小
函数的定义
具备某一项功能的工具即函数;函数的使用必须遵循:先定义,在调用。
函数分类:
- 1、内置函数:Python解释器自带的函数,Python解释就会启动
例如:len()、max()、min()等
- 2、自定义函数:
语法:
def 函数名(参数1,参数2,)
'''注释'''
函数体
return 返回值
函数的传参
1:形参与实参
形参:在函数定义阶段,括号内定义的参数的称为形参,就相当于变量名
实参:在函数调用阶段,括号内定义的参数的称为实参,就相当于变量值
在调用阶段,实参的值会绑定给形参,在调用结束后,解除绑定
参数的分类:
一:位置参数
位置形参:必须被传值的参数,多一个不行,少一个也不行
位置实参:从左到右依次赋值给形参
二:关键字参数:在函数调用阶段,按照key=value的形式定义实参
可以不依赖位置而指名道姓地给形参传值
需要注意的问题(可以与位置实参混用,但是):
- 位置实参必须在关键字实参的前面
- 不能为一个形参重传值
三:默认参数:在定义函数阶段,已经为形参赋值了,在定义阶段已经赋值,意味着在调用阶段可以不传值注意的问题:
1 默认参数的值,只在定义时赋值一次 2 位置形参应该在默认参数的前面 3 默认参数的值应该是不可变类型
四:可变长参数
实参可变长度指的是:实参值的个数是不固定
而实参的定义形式无非两种:1、位置实参,2、关键字实参
针对这两种形式的实参个数不固定,相应的,形参也要有两种解决方案
五:命名关键字参数(了解):
形参中,在*后定义的参数称之为命名关键字参数,
它的特性是;传值时,必须按照关键字实参的形式传值
名称空间:存放名字与值绑定关系的地方
内置名称空间:
存放的是:内置的名字与值的绑定关系
生效:python解释器启动
失效:Python解释器关闭
全局名称空间
存放的是:文件级别定义的名字与值的绑定
生效:执行python文件时,将该文件级别定义的名字与值的绑定关系存放起来
失效:文件执行完毕
局部名称空间
存放的是:函数内部定义的名字与值的绑定关系
生效:调用函数时,临时生效
失效:函数调用结束
加载顺序:先内置,再全局,最后局部
查找名字的顺序:先局部,再全局,最后内置
x=10
if x > 3:
y=2
def foo(a,b): #a='aaaa' b='bbbb'
m=11111
n=2222
def bar():pass
foo('aaaa','bbbb')
max=10
def f1():
max='f1'
def f2():
max='f2'
print(max)
f2()
f1()
print(max)
作用域:
全局作用域:包含内置名称空间的名字与全局名称空间的名字
全局存活,全局有效
局部作用域:包含局部名称空间的名字
临时存活,局部有效
x=1011111111111111111111111111111111111111111
def f1(a):
y='fffffffffffffffffffffffffffffff1'
# print(locals())
print(globals())
print(globals())
print(dir(globals()['__builtins__']))
print(locals() is globals())
f1(12321312312312312312312312312312312312313213)
作用域关系,在函数定义时,就已经固定了,与调用位置无关
x=10000000000000000000000000
def f1():
def f2():
# x='123123123123123123123123123123123'
print(x)
return f2
f=f1()
# print(f)
def func():
x=123
f()
x='hello'
func()
global nonlocal
x=1
def f1():
global x
x=10
f1()
print(x)
x=1
def f1():
x=2
def f2():
nonlocal x
x=111111
f2()
print(x)
f1()