八:《Python基础语法汇总》— 三器一闭与文件操作

简介: 本篇文章讲解了函数的闭包;装饰器;迭代器及生成器。和对文件的操作(如:对文件的打开;关闭;读;写;复制等)

一:三器一闭

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" 模式进行写入:

  1. ​ 如果这个文件名已经存在,用 "w" 模式打开则会清空文件中的内容
  2. ​ 如果这个文件名不存在,"w" 模式则会进行新建
  3. ​ 不管文件是否存在,只要用"w" 模式打开,以往的内容都会被新输入的内容给替换掉
#用相对路径来完成写入:

a = open("fi.txt","w",encoding = "utf-8")
#用open()函数打开的内容是文件的一个可迭代对象,并不会直接把内容给到你
a.write("Hello!")
#write()是用来在文件中写入一个内容

注意: write() 没有返回值,直接去文件中查看写入的内容即可

"a" 模式用于追加:

  1. ​ 当文件名不存在时,"a" 模式则会进行新建
  2. ​ 当文件名存在时,用 "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:

  1. with 是上下文管理器,当文件打开,带缩进的代码执行完毕后,会自动把文件关闭
  2. 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(文件目录)
目录
相关文章
|
6天前
|
存储 Python
Python文件操作(1)
【10月更文挑战第17天】
Python文件操作(1)
|
4月前
|
监控 Java 数据处理
文件操作不再难!Python系统编程实战,带你轻松驾驭文件系统与I/O
【7月更文挑战第31天】在 Python 系统编程中, 文件操作与 I/O 管理至关重要。
56 2
|
5天前
|
数据采集 存储 Python
Python文件操作2
【10月更文挑战第18天】
Python文件操作2
|
5月前
|
开发者 Python
Python基础第七篇(Python的文件操作)
Python基础第七篇(Python的文件操作)
|
2月前
|
存储 Python
Python文件操作
Python文件操作
|
2月前
|
存储 安全 Python
30天拿下Python之文件操作
30天拿下Python之文件操作
31 1
|
5月前
|
存储 安全 开发者
文件操作?Python让你轻松搞定!
【6月更文挑战第12天】Python编程中的文件操作至关重要,涉及数据存储和系统交互。通过内置的`open()`函数,开发者可轻松处理文件。以只读模式`'r'`为例,使用`with`语句打开并读取文件内容;写入文件则用`'w'`或`'a'`模式。文件对象还支持高级功能,如文件指针移动,允许随机访问。掌握这些技能能提升开发效率。
31 0
|
25天前
|
Java 程序员 Python
【Python】文件操作
【Python】文件操作
18 0
|
2月前
|
监控 安全 Java
文件操作不再难!Python系统编程实战,带你轻松驾驭文件系统与I/O
【9月更文挑战第13天】在Python系统编程中,文件操作与I/O管理至关重要。本文通过五个实战案例分享最佳实践:高效遍历文件系统、优雅处理文件读写、利用缓冲机制优化性能、并行处理文件加速任务以及异常处理确保程序稳健。使用pathlib、上下文管理器及concurrent.futures等工具,助你轻松掌握Python文件系统与I/O操作,提升编程效率和项目质量。 示例代码展示了如何使用pathlib遍历目录、with语句安全读写文件、控制缓冲区大小、并行处理多个文件以及捕获异常保证程序稳定运行。通过这些技巧,你将能够在实际项目中更加高效地管理和操作文件。
44 6
|
3月前
|
IDE 测试技术 开发工具
Python接口自动化测试框架(基础篇)-- 不只是txt的文件操作
本文介绍了Python中的文件操作方法,包括使用open()打开文件、close()关闭文件、read()读取内容、readline()读取单行、readlines()读取多行、write()写入内容以及writelines()写入多行的方法。同时,探讨了文件操作模式和编码问题,并扩展了上下文管理器with...as的使用,以及对图片和音频文件操作的思考和练习。
27 1
Python接口自动化测试框架(基础篇)-- 不只是txt的文件操作