一:三器一闭
1.闭包:
闭包是高阶函数的一种实现方式,是一个特殊的高阶函数,闭包可以延长函数中局部变量的生命周期,可以将外层函数内的局部变量持久的保存在内存中,即使外层函数的空间被释放,这些变量也不会销毁,而是会被保留直到闭包被销毁
如何实现闭包:
1.嵌套函数
2.外层函数返回内层函数的地址
3.内层函数使用外层函数的变量
#闭包函数的实现,要同时满足以上三点
def a(x):
def b(y):
return x+y
return b
qiao = a(55) #返回值 = 函数名() 所以qiao接收到的就是函数b的地址
print(qiao(78)) #地址名加括号相当于函数的调用
注意: 闭包一定要有至少一个参数,用来接收函数地址
2.装饰器:
装饰器是一个非常强大的工具,它可以在不改变原函数的基础上,给函数增添新的功能,装饰器本质上就是一个闭包函数,接收一个函数作为参数,并返回一个修改后的函数
#给这个函数增添查询的功能 -- 装饰器
li = []
def qiao(ze): #ze接收传入的参数;ze这个形参就是用来接收主函数的
def aa(name):
ze(name)
print("开始查询")
if name in li:
print("已存在")
return aa
#将装饰器加装到原函数的身上
@qiao #调用装饰器,接收一个函数并返回一个新的函数 yue = qiao(yue);把yue函数当成参数传递给qiao函数
#原函数
def yue(name):
li.append(name)
print(li)
yue("gugu") #这里是在调用aa函数,"gugu"为aa的参数
注意:
- 装饰器一定是一个闭包,且一定要写在要装饰的函数的函数名上面
- 调用装饰器: @外层函数名
3.迭代器:
迭代就是依次访问可迭代对象元素的过程,把这样的过程称之为遍历也叫迭代
(1)判断是否为可迭代对象
可迭代对象是指可以被 for循环 遍历的对象,在Python中,dir()
可以查看对象的所有属性和方法,只要实现了 iter()
方法,就可以被称为可迭代对象
print(dir([1,2])) #查看列表所拥有的一些属性和方法,如果里面发现有iter()方法,说明它就是一个可迭代对象
注意: iter()
是将可迭代对象转换为迭代器,而不是将任意的类型转换为迭代器
from collections.abc import Iterable
a = iter([23,455,88]) #将列表转换为迭代器
print(isinstance(a,Iterable))
使用内置函数 isinstance()
来判断一个对象是否是可迭代对象,或用来判断某一对象是什么类型
from collections.abc import Iterable #此函数使用时要导入
print(isinstance("tfyudxectuy",Iterable)) #判断此类型是否为Iterable类型,是为True,不是为False
注意: Iterable
是迭代器的意思
from collections.abc import Iterable
print(isinstance(123,int)) #判断123是否为int类型
注意:
- 容器都是可以被迭代的
- 只要是能被
for
循环所遍历的就都是可迭代对象
(2)迭代器的本质
- 迭代器是Python中访问元素的方式,它可以记住遍历的位置,直到所有的元素被访问结束
- 迭代器与可迭代对象是有区别的,可迭代对象可以理解为是存储多个元素的容器,但是迭代器本身并不存储数据,而是等到用到时才生成数据,因此,迭代器要比容器更加的节省内存
- 迭代器本身是通过
next()
函数去获取下一条数据,for
循环的本质就是将可迭代对象转换为迭代器,然后调取next()函数依次取值
#for循环的原理
li = [24,4,5,885,25,240]
lion = iter(li) #通过一个变量拿到这个列表的迭代器
while True:
try: #异常捕获
next(lion) #通过next()函数取值
except StopIteration: #捕获StopIteration异常
break
注意: 迭代器中无法用过索引去取值,因为迭代器中的数据是一个一个生成的,索引索取不到,只能够通过next()
函数去一个一个获取到其中的值
li = [24,4,5,885,25,240]
lion = iter(li) #通过一个变量拿到这个列表的迭代器
print(next(lion)) #next()函数获取到迭代器中的第一个值并打印输出
print(next(lion)) #next()函数获取到迭代器中的第二个值并打印输出
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
for i in lion: #从第三个值开始获取
print(i)
注意: next()
函数有记忆力,已经访问过的元素就不会在重复去访问了,因为for
循环本身就是通过调取next()
函数去取值,而next()
函数已经取过两个值了,所以不会再次去访问这两个值了,这就是为什么迭代器能够记住当前访问的位置
4.生成器:
生成器是特殊的迭代器,在需要数据时才会生成值,本身不会去存储数据,从而节省内存,生成器的创建方式要比迭代器简单很多,在Python中使用 yield 关键字来定义一个生成器函数
def we():
yield 1 #返回1这个值给到生成器,并暂停执行
yield 2 #第二个next()函数取值,因为有yield,又再次暂停执行
yield 3
x = we() #通过一个变量获取到生成器对象
print(next(x))
print(next(x))
注意:
- 如果函数中有
yield
这个关键字,那么这个函数就是生成器函数 - 生成器函数不能通过普通的函数调用获取值,而要通过
next()
函数去获取生成器函数里的值 - 生成器函数会通过
yield
这个关键字自动暂停执行,暂停的只是函数体,不耽误后续代码
生成器的第二种创建方式:(表达式 for 变量 in 可迭代对象)
from collections.abc import Iterable
a = (i for i in range(56,79))
print(a)
print(isinstance(a,Iterable))
print(next(a))
二:文件操作
1.文件操作的作用:
(1)文件操作包含:打开;关闭;读;写;复制等
(2)文件操作的作用:读取内容;写入内容;备份内容等,把一些内容或数据给存储起来,可以让程序在下一次执行的时候直接使用,而不必重新制作一份,省时省力
(3)文件与数据库的区别:
相同点:都是用来存储数据且对数据进行持久化的存储
不同点:文件操作是在本地进行持久化存储;而数据库是一个远程的持久化
(4)文件的路径:
相对路径:同级路径,在当前文件夹下通过名称去查找
e.g. 上一级的文件名\\01.txt
绝对路径:从当前磁盘下的根目录去查找
e.g. D:\文件名\文件名\01.txt
2.文件的基本操作:
一:通过 open(filename,打开文件的模式,encoding = "utf-8")
函数:打开本地的文件或文件夹
-
filename
参数:指定文件的路径(相对路径或绝对路径),要把所要查找的具体文件名也写上 -
encoding
参数:指定文件的编码,默认Utf-8
编码
注意: open()
函数只会帮你把文件打开,不会帮你把文件关闭
文件的基本操作:
模式 | 描述 |
---|---|
w |
打开一个文件只用于写入;如果该文件已存在则打开文件且原有内容会被删除,从头开始重新写入;如果该文件不存在则创建新文件 |
r |
以只读的方式打开文件,只能打开已经存在的文件,光标会放在最前面 |
a |
打开一个文件用于追加;如果该文件已存在,光标会放在文件的结尾追加写入,也就是新的内容将会被写入到已有内容之后;如果该文件不存在则创建新文件进行写入 |
w+ |
在 "w" 模式的基础上附加读取(read )权限 |
r+ |
在 "r" 模式的基础上附加写入(write )权限,r+ 的本质就是对原本内容的覆盖 |
a+ |
在 "a" 模式的基础上附加读取(read )权限 |
wb |
以二进制的格式打开一个文件只用于写入;如果该文件已存在则打开文件且原有内容会被删除,从头开始重新写入;如果该文件不存在则创建新文件,一般用于非文本文件 |
rb |
以二进制的格式打开一个文件用于只读,文件的光标会放在最前面,一般用于非文本文件 |
ab |
以二进制的格式打开一个文件用于追加;如果该文件已存在,光标会放在文件的结尾追加写入,也就是新的内容将会被写入到已有内容之后;如果该文件不存在则创建新文件进行写入 |
wb+ |
以二进制的格式打开一个文件用于读取和写入,如果该文件已存在则打开文件且原有内容会被删除,从头开始重新写入;如果该文件不存在则创建新文件,一般用于非文本文件 |
rb+ |
以二进制的格式打开一个文件用于读取和写入,文件的光标会放在最前面,一般用于非文本文件 |
ab+ |
以二进制的格式打开一个文件用于追加;如果该文件已存在,光标会放在文件的结尾追加写入,也就是新的内容将会被写入到已有内容之后;如果该文件不存在则创建新文件用于读取和写入 |
注意:
- 当在
open()
函数中不写入模式时,那么会自动默认为"r"
模式 - 用于非文本文件指的是图片;视频等,多用于爬虫
(1)read()
读取:"r"
模式只支持读取
-
"r"
模式只能够打开已经存在的文件,无法进行新建操作,光标在最前面 -
read()
读取返回的数据类型是字符串
#用相对路径来完成读取:
a = open("fi.txt","r",encoding = "utf-8")
#用open()函数打开的内容是文件的一个可迭代对象,并不会直接把内容给到你
#用变量a去接收,此时a是一个文件流;文件对象
print(a.read())
#read()是用来读取文件里面的一个内容
#用绝对路径来完成读取:
b = open(r"D:\asd\fgh\wem\fi.txt","r",encoding = "utf-8")
print(b.read())
readline()
和 readlines()
读取:
-
readlines()
默认读取的是整个内容,读取的是一个字符串,按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素 -
readline()
是一行一行读取的,读取的是光标所在行,一般用于for
循环
#读取所有内容
a = open("fi.txt","r",encoding = "utf-8")
print(a.readlines())
#读取第一行
a = open("fi.txt","r",encoding = "utf-8")
print(a.readline())
(2)write("要写入的内容")
写入:write
只能写入字符串
"w"
模式进行写入:
- 如果这个文件名已经存在,用
"w"
模式打开则会清空文件中的内容 - 如果这个文件名不存在,
"w"
模式则会进行新建 - 不管文件是否存在,只要用
"w"
模式打开,以往的内容都会被新输入的内容给替换掉
#用相对路径来完成写入:
a = open("fi.txt","w",encoding = "utf-8")
#用open()函数打开的内容是文件的一个可迭代对象,并不会直接把内容给到你
a.write("Hello!")
#write()是用来在文件中写入一个内容
注意: write()
没有返回值,直接去文件中查看写入的内容即可
"a"
模式用于追加:
- 当文件名不存在时,
"a"
模式则会进行新建 - 当文件名存在时,用
"a"
模式可以在原来内容的末尾去添加新内容,不会发生替换和清空,光标在最后面(光标在哪个位置就从哪个位置开始写;但如果光标在最前面,则会发生清空替换)
#用相对路径来完成写入:
b = open("fi.txt","a",encoding = "utf-8")
#用open()函数打开的内容是文件的一个可迭代对象,并不会直接把内容给到你
b.write("I like you!")
#write()是用来在文件中写入一个内容
(3)用 "w+"
进行写入读取操作:
a = open("fi.txt","w+",encoding = "utf-8")
print(a.read()) #此时无法进行读取,因为"w+"模式是在"w"模式的基础上进行操作的,而"w"模式会进行清空操作
a = open("fi.txt","w+",encoding = "utf-8")
a.write("I like you")
print(a.read()) #此时依旧无法进行读取,因为光标问题,在写入内容之后光标已经在最后面了,所以读取不到内容
此时就用到了seek()
函数:移动光标,通过设置里面的参数从而控制光标的移动位数
a = open("fi.txt","w+",encoding = "utf-8")
a.write("I like you")
a.seek(0) #将光标移动到最前方
print(a.read()) #此时可以完成读取,读取到的内容为新写入的内容,因为以往的内容已经被"w"模式给清空了
注意: 每次写入时,"w+
" 模式都会将以往的内容给清空覆盖
(4)用 "r+"
进行写入读取操作:
-
tell()
函数:查看当前文件的光标位置 -
close()
函数:关闭当前文件
a = open("fi.txt","r+",encoding = "utf-8")
a.write("I like you")
print(a.tell())
a.seek(0)
print(a.read(6)) #读取6个位置
a.close()
注意:
- 多注意光标位置,如果不对就进行调整
- 当重复执行时一样的内容时,
"r+"
模式不会多次写入,也不会对以往的内容进行覆盖
(5)用 "a+"
进行写入读取操作:
a = open("fi.txt","a+",encoding = "utf-8")
a.write("I like you")
print(a.tell())
a.seek(0)
print(a.read(9)) #读取9个位置
a.close()
注意: 当重复执行一样的内容时 "a+"
模式会多次写入,但不会覆盖原本写入的内容
二:通过 with open(文件的路径,打开文件的模式,encoding = "指定的文件编码") as f:
-
with
是上下文管理器,当文件打开,带缩进的代码执行完毕后,会自动把文件关闭 -
f
是临时变量名,只在with open()
里有用,出了with open()
再用会报错
with open("fi.txt","r+",encoding = "utf-8") as f:
print(f.read())
f.write("I like you")
注意: 缩进和光标的位置,一直打开文件会占用内存空间,如果用 open()
函数的话记得关闭文件
备份一个文件:
#复制操作
a = "fi.txt"
with open(a,"r",encoding = "utf-8")as i:
b = i.read()
print(b)
#新建文件并粘贴的操作
with open("beifen.txt","w",encoding = "utf-8")as i:
i.write(b)
题目:张三办了一张银行卡,里面没有一分钱,现在他要进行存钱和取钱的操作
1.编写两个函数:
(1)存钱函数:save_money()
(2)取钱函数:get_money()
2.创建一个bank_card.txt的文本文档,充当银行卡
要求:
1.当调用存钱函数时,我们输入的金额将会存储在bank_card.txt银行卡中
2.当调用取钱函数时,我们输入的金额将会在bank_card.txt银行卡中扣除
#办银行卡
with open("bank_card.txt","w",encoding = "utf-8") as i:
i.write("0") #没有一分钱,表示开卡成功
#创建存钱函数:save_money()
def save_money(money): #传入参数(存入的金额)
with open("bank_card.txt","r+",encoding = "utf-8") as f: #在存钱之前要先读取知道原本有多少钱,在与存入的钱进行累加
look = float(f.read()) #此时要先进行读取,在与存入的数字进行累加,最后在去写入;因为相加是变量与变量之间所以要把读取的内容存入到变量中
look += money #读取到的金额加上存入的金额
f.seek(0) #要时刻注意光标的位置
save = float(f.write(f"{look}")) #将金额存入到银行卡中
print(look)
save_money(678.9) #调用函数进行存钱操作
save_money(567)
#创建取钱函数:get_money()
def get_money(money): #传入的参数(取出的金额)
with open("bank_card.txt","r",encoding = "utf-8") as f: #读取
'''
此时这里不能使用r+因为r+的本质是覆盖,而取钱会造成钱的数量减少,覆盖不到位的情况
也不能使用w+因为w会先造成清空的操作
这里应先进行两次操作,先读取,再用读取到的金额减去取出的金额,最后再写入
'''
look = float(f.read())
with open("bank_card.txt", "w", encoding="utf-8") as f: #写入,此时已经将数据读取并保存到变量中了,就算清空也没有关系了
if money > look:
print("您的银行卡余额不足,请重新输入~~~")
f.write(f"{look:.1f}")
print(f"{look:.1f}")
else:
look -= money
# f.write(str(look))
f.write(f"{look:.1f}") #写入时后面仅保留一位小数
print(f"{look:.1f}") #输出时后面仅保留一位小数
get_money(10000) #调用函数进行取钱并查看剩余金额
3.文件和文件夹:
在 Python 中文件和文件夹的操作要借助 os
模块里面的相应功能,os
模块是内置模块,无需安装
os 模块的使用:
(1)导入模块
import os
(2)文件重命名
os.rename(目标文件名,新文件名)
(3)删除文件
os.remove(目标文件名)
(4)创建文件夹
os.mkdir(文件夹名字)
(5)删除文件夹
os.rmdir(文件夹名字)
(6)获取当前文件目录路径
os.getcwd()
(7)改变默认目录
os.chdir(目录)
(8)获取目录列表
os.listdir(文件目录)