巨蟒python全栈开发-第8天 文件操作

时间:2023-03-09 02:33:18
巨蟒python全栈开发-第8天 文件操作

一.文件操作

今日大纲:

1.文件操作->open()
open 打开
f=open(文件路径,mode='模式',encoding='编码格式')
#python最最底层操作的就是bytes
打开一个文件的时候获取到的是一个文件句柄(#相当于插了一根管子) 绝对路径
从磁盘根目录开始寻找
相对路径
相对于当前程序所在的文件夹
../上一层文件
文件夹/进入xxx文件夹
2.mode:
高频: r r+ rb
w wb
a
了解: w+ a+ ab
r+b w+b a=b
(1)r:读取,只读,读取文件的相关操作
1.read()
默认:读取全部文件内容
read(n) 读取n个字符
2.readline() 读取一行内容
3.readlines() 读取全部内容,返回列表
4.for line in f:每次读取一行内容:(最重要的)
(注意在这里打印出来的有一个空行,需要strip()去掉空行) (2)w:写入:写文件的相关操作
1.写入,只写
2.创建文件
3.会清空文件
(3)a:追加
1.也可以创建文件
2.追加写
(4)r+:
1.对于文件而言,应该有的操作就两个:读,写
2.读写操作
(5)w+:写读操作
(6)a+:追加写读
(7)所有带b的表示直接操作的是bytes,当处理非文本文件的时候
例如:rb/wb
ab:断点续传//别人写好来了专门的库,可以直接用
r+b w+b a+b
3.文件操作中关于文件句柄的相关操作
(1)seek() 移动光标
seek详解:
f.seek(0) 移动到开头(最多)
f.seek(0,2) 移动到结尾,seek的第二个参数表示的是从哪个位置进行偏移
默认是0,表示开头,1表示当前位置,2表示结尾
seek:两个参数
1.表示偏移量
2.从xxx开始偏移,默认0,开头位置 1 当前位置 2 末尾位置 f.seek(10,1) #从当前位置走10步
f.seek(10,2) #从末尾位置走10步 (2)tell:返回光标所在的位置
(3)seek/tell/truncate,这三个方法的参数,都是字节的
4.实际操作,文件修改(重点)
#python是最终是以字节形式操作文件的

DAY8-文件操作

本节主要内容:

(1)r模式初识
(2)文件路径的问题
(3)r模式
(4)w模式
(5)a模式
(6)+模式
(7)文件复制bytes rb/wb模式
(8)seek和tell
(9)文件修改
(10)水果统计 内容详解:
(1)r模式初识    r:read 只读
文件里的内容:alex周杰伦昆凌周润发
f=open('小护士模特主妇萝莉',mode='r',encoding='utf-8')
#读取内容
content=f.read()#全部都读取出来(最后光标就在末尾了)
print(content) #坑:
c2=f.read() #注意:第二次读取,读取不到内容,因为上面已经读取完毕,光标在末尾
print('c2',c2)  #结果显示的是第一个c2,第二个c2已经没有东西可读了 #良好的习惯
f.close() #关闭连接 #结果:alex周杰伦昆凌周润发
# c2

主要:f.close()的位置

(2)文件路径的问题
文件路径:
1.相对路径:相对于当前程序所在的文件夹,如果在文件夹内,随便找,直接写名字
如果不在这个文件夹内容,可能需要 出文件夹或者进文件夹
出文件夹 ../
进文件夹 文件夹/

巨蟒python全栈开发-第8天 文件操作

对上图进行解释:金庸是根目录,它的子目录包括:天龙八部,射雕,金庸大杂烩.py

      天龙八部下面的文件是:乔峰

      射雕下面的文件是:九阴真经,洪七公,郭靖

      九阴真经下面的文件是:梅超风.py

对于同一根文件"金庸"下的,''金庸大杂烩.py'',我们,直接找并列的,兄弟文件就行

f = open("天龙八部/乔峰", mode="r", encoding="utf-8")
content = f.read()
print(content) f = open("射雕/郭靖", mode="r", encoding="utf-8")
content = f.read()
print(content)

对于同一根文件'金庸'下的 '梅超风.py',找乔峰文件,按照上边的思维是应该按照上边的写法!!!!!!!

f = open("九阴真经/射雕/天龙八部/乔峰", mode="r", encoding="utf-8")
print(f.read())
f.close()

但是上边的写法是错误的,我们应该把往上层走的文件用../表示,所以应该是下面写法,并列走,不能替换,往下走也不能替换

f = open("../../天龙八部/乔峰", mode="r", encoding="utf-8")
print(f.read())
f.close()

同理,'洪七公.py'找'乔峰',应该往上走一层,再找兄弟,再往下走

f = open("../天龙八部/乔峰")
2.绝对路径:从磁盘根目录寻找路径(有问题)
只有在记录日志的时候可以用到绝对路径
日志:程序运行过程中记录的信息 (尤其是游戏公司)

绝对路径案例:

f=open('F:\spython\西游记\金角大王.txt',mode='r',encoding='gbk')
print(f.read())
f.close()

在windows10中,txt文件直接写的中文是gbk,所以写的是gbk,直接用gbk解码

(3)r模式

1.文件内容:alex周杰伦昆凌周润发
f=open('小护士模特主妇萝莉',mode='r',encoding='utf-8')
print(f.read()) #alex周杰伦昆凌周润发
f.close()
2.
f=open('小护士模特主妇萝莉',mode='r',encoding='utf-8')
print(f.read(5)) #读取5个字符   #结果:alex周
print(f.read(5)) #继续读取5个字符 #结果:杰伦昆凌周
f.close() 3.
f=open('小护士模特主妇萝莉',mode='r',encoding='utf-8')
print('xxxxx\n',end='') #结果:xxxxx #\n代表换行
print(f.readline()) #读一行: alex周杰伦昆凌周润发 结果:xxxxx
   alex
4.文件内的\n打印出来的还是\n 5.最好用的方式,没有之一
#文件句柄是一个可迭代对象 f=open('小护士模特主妇萝莉',mode='r',encoding='utf-8')
for line in f: #从文件
print(line.strip())
# print(line) 6. print(f.readline().strip()) # 换行符为分割, strip()可以去掉换行. 读取到的内容第一件事就是去掉空白
  print(f.readline()) # 换行符为分割 7.
print("周润发", end="胡辣汤")
print("周润发")
结果:周润发胡辣汤周润发 8.print(f.readlines()) # 一次性把文件中的内容读取到列表中.
9.
print("你叫什么名字?\n 我叫李嘉诚. 可能") #  换行
print("你叫什么名字?\\n 我叫李嘉诚. 可能") # 显示 \n
print("你叫什么名字?\\\\n 我叫李嘉诚. 可能") # 显示 \\n
结果:

  你叫什么名字?
  我叫李嘉诚. 可能
  你叫什么名字?\n 我叫李嘉诚. 可能
  你叫什么名字?\\n 我叫李嘉诚. 可能

(4)w模式
每次用w模式打开文件,都会清空这个文件(坑)
尤其是日志,不能用w模式写
f=open('胡辣汤',mode='w',encoding='utf-8')     #可以帮我们创建文件
f.write('河南特色\n')   #写一行就换行
f.write('东北特色\n')
f.write('陕西特色\n')
#好习惯
f.flush() #刷新管道,把数据写入文件
f.close()

(5)a模式

f=open('胡辣汤',mode='a',encoding='utf-8') #a,append 追加,在文件的末尾写入内容

f.read() #报错 not readable

f.write('你叫什么名字啊?')
f.close()

(6)+模式

r+

f=open('葫芦小金刚',mode='r+',encoding='utf-8')
content=f.read() #顺序必须先读,后写
#r+特有的深坑:不论读取内容的多少,只要你读了,写就是在末尾
f.write('五娃')
print(content)

w+

#w+一上来会清空文件. 没人用
f = open("葫芦小金刚", mode="w+", encoding="utf-8")
f.write("又能吐火的, 有能吐水的.")
# 移动光标
f.seek(0) # 移动到开头
s = f.read()
print("=========>", s)

a+

#a+追加写读,光标在末尾,所有的写都是在末尾
f=open('葫芦小金刚',mode='a+',encoding='utf-8')
f.write('丢丢丢,机器葫芦娃召唤神龙,高喊,我代表月亮消灭你!')
f.seek(0)
s=f.read()
print('===>',s)

(7)文件复制bytes

#注意这个路径的写法,我困在这个地方很久,如果不加/,在当前目录下创建一个新的一模一样的图片,必须在pycharm的文件路径下才能删除

f1=open('d:/huyifei.jpg',mode='rb')
f2=open('f:/huyifei.jpg',mode='wb')
for line in f1: #line是从f1中读取的内容 #里边会自己分行
f2.write(line) #把读取的内容原封不动的写出去
f1.close()
f2.flush()
f2.close()

(8)seek&tell

f = open("胡辣汤", mode="r+", encoding="utf-8")
# f.seek(0,2) # 移动到末尾
# content = f.read(5)
# print(content)
# f.seek(0) # 移动到开头
# print(f.read()) #读取全部内容
# print(f.tell()) # 字节 f.seek(3)
print(f.read())

tell和seek和truncate都是字节码个数

(9)文件修改:

文件内容:

alex是一个大好人
好人一生平安
好人是alex
你是一个好人
需求:把好人换成sb
必须做的事:
1.先从文件中读取内容
2.把要修改的内容进行修改
3.把修改好的内容写入一个新文件
4.删除掉原来的文件
5.把新文件重命名成原来的文件的名字
导入os模块//os模块表示操作系统

方法一:
#with会自动的帮我们关闭文件的链接
with open('夸一夸alex',mode='r',encoding='utf-8') as f,\
open('夸一夸alex_副本',mode='w',encoding='utf-8') as f1:
for line in f:
if 'sb' in line:
line=line.replace('sb','好人')
f1.write(line)
import os
import time time.sleep(3) #在删除程序之前,先让程序睡3s(程序暂停三秒)
os.remove('夸一夸alex') #删除原来文件
time.sleep(3) # 在pycharm中显示不明显,在原来的文件目录中可以明显观察到变化
os.rename('夸一夸alex_副本','夸一夸alex') #重命名副本为原来的文件

方法二:

f=open('夸一夸alex',mode='r',encoding='utf-8')
f2=open('夸一夸alex_副本',mode='w',encoding='utf-8') for line in f:
if '好人' in line:
line=line.replace('好人','sb')
f2.write(line)
f.close()
f2.flush()
f2.close() import os
import time time.sleep(3) #在删除程序之前,先让程序睡3s(程序暂停三秒)
os.remove('夸一夸alex') #删除原来文件
time.sleep(3) # 在pycharm中显示不明显,在原来的文件目录中可以明显观察到变化
os.rename('夸一夸alex_副本','夸一夸alex') #重命名副本为原来的文件

(10)水果统计

文档:

1,香蕉,1.85,50
2,苹果,2.6,100
3,榴莲,25,800
4,木瓜,3.5,1000
处理一:
f=open('水果.txt',mode='r',encoding='utf-8')
for line in f: #1,香蕉,1.85,50
dic={} #每行都是一个字典
line=line.strip() #去掉空白 \n 1,香蕉,1.85,50
a,b,c,d=line.split(",") #[1,香蕉,1.85,50]
dic['id']=a
dic['name']=b
dic['price']=c
dic['totle']=d
print(dic)
# 结果:
# {'id': '1', 'name': '香蕉', 'price': '1.85', 'totle': '50'}
# {'id': '2', 'name': '苹果', 'price': '2.6', 'totle': '100'}
# {'id': '3', 'name': '榴莲', 'price': '25', 'totle': '800'}
# {'id': '4', 'name': '木瓜', 'price': '3.5', 'totle': '1000'}

处理二:

#把字典装到列表里
f=open('水果.txt',mode='r',encoding='utf-8')
lst=[]
for line in f: #1,香蕉,1.85,50
dic={} #每行都是一个字典
line=line.strip() #去掉空白 \n 1,香蕉,1.85,50
a,b,c,d=line.split(",") #[1,香蕉,1.85,50] #解构
dic['id']=a
dic['name']=b
dic['price']=c
dic['totle']=d
lst.append(dic)
print(lst)
#结果:
# [{'id': '1', 'name': '香蕉', 'price': '1.85', 'totle': '50'},
# {'id': '2', 'name': '苹果', 'price': '2.6', 'totle': '100'},
# {'id': '3', 'name': '榴莲', 'price': '25', 'totle': '800'},
# {'id': '4', 'name': '木瓜', 'price': '3.5', 'totle': '1000'}]

升级处理文档:

编号,名称,价格,重量
1,香蕉,1.85,50
2,苹果,2.6,100
3,榴莲,25,800
4,木瓜,3.5,1000
处理一:
f=open('水果.txt',mode='r',encoding='utf-8')
line=f.readline() #第一行内容,编号,名称,价格,数量
h,i,j,k=line.split(',')
lst=[]
for line in f: #1,香蕉,1.85,50
dic={} #每行都是一个字典
line=line.strip() #去掉空白 \n 1,香蕉,1.85,50
a,b,c,d=line.split(",") #[1,香蕉,1.85,50] #解构
dic[h]=a
dic[i]=b
dic[j]=c
dic[k]=d
lst.append(dic)
print(lst)
#结果:#结果多了一个\n
# [{'编号': '1', '名称': '香蕉', '价格': '1.85', '重量\n': '50'},
# {'编号': '2', '名称': '苹果', '价格': '2.6', '重量\n': '100'},
# {'编号': '3', '名称': '榴莲', '价格': '25', '重量\n': '800'},
# {'编号': '4', '名称': '木瓜', '价格': '3.5', '重量\n': '1000'}]

处理二:

#在第2行,添加 strip()
f=open('水果.txt',mode='r',encoding='utf-8')
line=f.readline().strip() #第一行内容,编号,名称,价格,数量
h,i,j,k=line.split(',')
lst=[]
for line in f: #1,香蕉,1.85,50
dic={} #每行都是一个字典
line=line.strip() #去掉空白 \n 1,香蕉,1.85,50
a,b,c,d=line.split(",") #[1,香蕉,1.85,50] #解构
dic[h]=a
dic[i]=b
dic[j]=c
dic[k]=d
lst.append(dic)
print(lst) # 结果
# [{'编号': '1', '名称': '香蕉', '价格': '1.85', '重量': '50'},
# {'编号': '2', '名称': '苹果', '价格': '2.6', '重量': '100'},
# {'编号': '3', '名称': '榴莲', '价格': '25', '重量': '800'},
# {'编号': '4', '名称': '木瓜', '价格': '3.5', '重量': '1000'}]

处理三:最终版本,提升了程序的可扩展性

#推导步骤#将解包转化为列表,将分解完的,合成一个
f=open('水果.txt',mode='r',encoding='utf-8')
line=f.readline().strip() #第一行的内容, 编号,名称,价格,重量,哈哈
title=line.split(',') #title是一个列表 [编号,名称,价格,重量,哈哈]
lst=[]
# print(title) #老师帮忙调试
for line in f: #1,香蕉,1.85,50
dic={} #每一行都是一个字典
line=line.strip() #去掉空白 \n 1,香蕉,1.85,50
date=line.split(',') #[1,香蕉,1.85,50]
# print(date) #老师帮忙调试
for i in range(len(title)):
#title[i] & date[i]
dic[title[i]]=date[i]
lst.append(dic)
print(lst) # [{'编号': '1', '名称': '香蕉', '价格': '1.85', '重量': '50'},
# {'编号': '2', '名称': '苹果', '价格': '2.6', '重量': '100'},
# {'编号': '3', '名称': '榴莲', '价格': '25', '重量': '800'},
# {'编号': '4', '名称': '木瓜', '价格': '3.5', '重量': '1000'}]

Day08今日作业:

1,有如下文件,a1.txt,里面的内容为:

老男孩是最好的培训机构,
全心全意为学生服务,
只为学生未来,不为牟利。
我说的都是真的。哈哈 分别完成以下的功能: a,将原文件全部读出来并打印。
with open('a1.txt',mode='r',encoding='utf-8') as f:
ff=f.read()
print(ff)
b,在原文件后面追加一行内容:信不信由你,反正我信了。
with open('a1.txt',mode='a',encoding='utf-8') as f:
ff=f.write('\n信不信由你,反正我信了。')
c,将原文件全部读出来,并在后面添加一行内容:信不信由你,反正我信了。
with open('a1.txt',mode='r+',encoding='utf-8')as f:
fk=f.read()
print(fk)
ff=f.write('\n信不信由你,反正我信了。')
d,将原文件全部清空,换成下面的内容:

每天坚持一点,
每天努力一点,
每天多思考一点,
慢慢你会发现,
你的进步越来越大。
with open('a1.txt',mode='w',encoding='utf-8')as f:
ff=f.write('每天坚持一点,'
'\n每天努力一点,'
'\n每天多思考一点,'
'\n慢慢你会发现,'
'\n你的进步越来越大。')
e,将原文件内容全部读取出来,并在‘我说的都是真的。哈哈’这一行的前面加一行,
‘你们就信吧~’然后将更改之后的新内容,写入到一个新文件:a1.txt。
重点题目!!!
import os
with open('a1.txt',mode='r+',encoding='utf-8')as f ,\
open('a.txt',mode='w',encoding='utf-8')as f2:
for line in f:
f2.write(line.replace('我说的都是真的。哈哈','你们就信吧~,\n我说的都是真的。哈哈'))
os.remove('a1.txt')
os.rename('a.txt','a1.txt')
2,有如下文件,t1.txt,里面的内容为:

葫芦娃,葫芦娃,
一根藤上七个瓜
风吹雨打,都不怕,
啦啦啦啦。
我可以算命,而且算的特别准:
上面的内容你肯定是心里默唱出来的,对不对?哈哈 分别完成下面的功能: a,以r+的模式打开原文件,判断原文件是否可读,是否可写。
重点:上课没有讲过的方法
with open('t1.txt',mode='r+',encoding='utf-8') as f:
print(f.writable())
print(f.readable())
b,以r的模式打开原文件,利用for循环遍历文件句柄。
with open('t1.txt',mode='r',encoding='utf-8') as f:
for i in f:
print(i.strip()) #(1)
print(i,end='')   #(2)

上边(1)和(2)的作用是一样的,strip()和end=''的目的都是去除换行

c,以r的模式打开原文件,以readlines()方法读取出来,并循环遍历      
readlines(),并分析b,与c 有什么区别?深入理解文件句柄与readlines()结果的区别。
with open('t1.txt',mode='r',encoding='utf-8') as f:
ff=f.readlines()
# print(ff)
for i in ff:
print(i.strip())
  b是直接遍历句柄,读出来,
  c是先用readlines把文件内的信息放到列表中,相当于我们再遍历列表中的信息
d,以r模式读取‘葫芦娃’前三个字符。
with open('t1.txt',mode='r',encoding='utf-8') as f:
s=f.read(3)
print(s)
e,以r模式读取第一行内容,并去除此行前后的空格,制表符,换行符。(换行符是\n,制表符是\t(tab).\r)
with open('t1.txt',mode='r',encoding='utf-8') as f:
# k=f.readline().strip() #测试(1)
k=f.readline() #测试(2)
print(k) #测试的结果中(1)和(2)的结果是一样的

巨蟒python全栈开发-第8天 文件操作

f,以r模式打开文件,从‘风吹雨打.....’开始读取,一直读到最后。
with open('t1.txt',mode='r',encoding='utf-8') as f:
for i in f:
if i.startswith('风吹雨打'): #如果开头是"风吹雨打
# print(i,end='') #(1)把后边的换行去掉
# print(i) #中间会空一行,应该把后边的换行去掉
print(i.strip()) #(2)把后边的换行去掉 ,注意(1)和(2)的效果一样
print(f.read()) #从风吹雨打这一行最末尾,开始读剩下的信息
g,以a+模式打开文件,先追加一行:‘老男孩教育’然后在从最开始将原内容全部读取出来。
with open('t1.txt',mode='a+',encoding='utf-8') as f:
f.write('\n老男孩教育')
f.seek(0)
ff=f.read()
print(ff)
h,截断原文件,留下内容:‘葫芦娃’
#方法一:
with open('t1.txt',mode='a+',encoding='utf-8') as f:
f.truncate(9)  #注意这里的truncate是字节码的个数
f.seek((0))
print(f.read())
#方法二:
with open('t1.txt',mode='a+',encoding='utf-8') as f:
f.seek(9)
f.truncate()
f.seek(0)
print(f.read())
3.文件a.txt内容:每一行内容分别为商品名字,价钱,个数。

apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3 通过代码,将其构建成这种数据类型:
[{'name':'apple','price':10,'amount':3},{'name':'tesla','price':1000000,'amount':1}......]
并计算出总价钱。
with open('a.txt',mode='r',encoding='utf-8') as f:
lst=[]
for i in f:
dic = {}
s=i.split()
# print(s)
dic['name']=s[0]
dic['price']=s[1]
dic['amount']=s[2]
lst.append(dic)
# print(dic)
print(lst)
sum=0
for k in lst:
sum+=int(k['price'])*int(k['amount'])
print(sum)
4,有如下文件:

alex是老男孩python发起人,创建人。
alex其实是人妖。
谁说alex是sb?
你们真逗,alex再牛逼,也掩饰不住资深屌丝的气质。 将文件中所有的alex都替换成大写的SB(文件的改的操作)。
with open('pythonalex',mode='r',encoding='utf-8') as f,\
open('pythonalex_911',mode='w',encoding='utf-8')as f1:
for i in f:
if 'alex' in i:
i=i.replace('alex','SB') #这个地方必须用等于
f1.write(i)
import os
os.remove('pythonalex')
os.rename('pythonalex_911','pythonalex')
5,文件a1.txt内容(升级题)

name:apple price:10 amount:3 year:2012
name:tesla price:100000 amount:1 year:2013
....... 通过代码,将其构建成这种数据类型:
[{'name':'apple','price':10,'amount':3},
{'name':'tesla','price':1000000,'amount':1}......]
并计算出总价钱。
#我把文件名改成了b1
with open('b1',mode='r',encoding='utf-8') as f:
lst=[]
for i in f:
dic={}
s=i.split() #字符串切割成列表:[name:apple,price:10,amount:3,year:2012]
for k in s:
l=k.split(':') #[name,apple]
dic[l[0]]=l[1]
dic.pop('year')
lst.append(dic)
print(lst)
sum=0
for z in lst:
sum+=int(z['price'])*int(z['amount'])
print(sum)
6,文件a1.txt内容(升级题)

序号     部门      人数      平均年龄      备注
1 python 30 26 单身狗
2 Linux 26 30 没对象
3 运营部 20 24 女生多
....... 通过代码,将其构建成这种数据类型:
[{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'},......]
with open('c1.txt',mode='r+',encoding='utf-8') as f:
# ff=f.readline().strip()
ff=f.readline()
s=ff.split() #列表:[序号,部门,人数,平均年龄,备注]
# print(s)
# f3=f.read()
# print(f3)
# print(s)
li=[]
for i in f: #i是: 1 python 30 26 单身狗
dic={}
# print(i.strip())
i=i.strip()
ii=i.split()
for z in range(len(s)):
dic[s[z]]=ii[z] #重点注意:在这里分割的是用ii,不是li,在这个地方纠结了好长时间
li.append(dic)
print(li)
明日默写:
就是第4题的代码(课上讲过)。