8 文件操作
8.1 写入文件
文本文件
python采用Unicode字符 以字符为单位进行处理
创建文件对象
open()
# 绝对路径
f = open(r"d:\b.txt","a") # 用r知道这是自由路径 不用写双\
r模式: 默认模式,文件不存在则报错
w模式: 文件不存在则创建,文件存在则覆盖
a模式: 文件不存在则创建,文件存在则不会覆盖,写内容会以追加的方式写(写日志文件的时候常用),追加模式是一种特殊的写模式
b(rb,wb,ab)模式:不用加encoding:utf-8
+ :可与其他模式组合
文本文件写入
步骤:
- 创建文件对象
- 写入数据
- 关闭文件对象
f = open("b.txt","a")
s = "hahaha\n"
f.write(s)
# 还有一个写入方法:
# writelines() 把字符串列表写入文件中,不添加换行符
f.close()
补 编码知识_中文乱码问题
ASCII -> ISO8859-1 -> GB2312 -> GBK -> GB18030
ASCII -> ISO8859-1 -> (不兼容)unicode
-> UTF-8(unicode的实际实现,变长编码)
编码解码不一致 就会乱码
8.2 关闭文件
close()
先把缓冲区数据写入文件(flush),再关闭文件,释放文件对象
try:
f = open(r"b.txt","a")
str = "hahaha"
f.write(str)
except BaseException as e:
print(e)
finally:
f.close()
8.3 with上下文管理器
str = "hahaha"
with open(r"d:\b.txt","a") as f:
f.write(str)
# 就酱就行,不用关闭文件
# 相当于with 可以自动还原
8.4 文本文件的读取
1. read(size)
以字符为单位,汉字 字母都算一个字符
2. readline(size)
读一行内容作为结果返回。读取到文件末尾,会返回空字符串
3. readlines(size)
每一行作为一个字符串存入列表中,返回该列表
以字符为单位,汉字 字母都算一个字符
# 加encoding 因为文件里中文英文都有
with open(r"d:\e.txt","r",encoding='utf-8') as f:
str = f.read(3) # 读取前三个 汉字也算一个
print(s)
# 按行读取一个文件
# 方法一 while
with open(r"d:\e.txt","r",encoding='utf-8') as f:
while True:
fragment = f.readline()
if not fragment:
break
else:
print(fragment,end="") # 因为readline()自带一个换行,print默认又自带一个换行,所以就设置一下呗
# 方法二 使用迭代器
with open(r"d:\e.txt","r",encoding='utf-8') as f:
for a in f:
print(a,end="")
-
enumerate()
把每个元素和索引关联起来(从0开始),同时用元组表示每个新的 索引,元素
python最重要的 写好推导式!这样能高效很多!
c = [ temp.retrip() # tempretrip()去空白符 这里去掉\n
+ " #" # 添加一个井号 一会要打出来
+ str(index) # str()方法把index这个数字转成字符串
for index,temp in enumerate(a) # 生成的列表来源于enumerate(a)
]
# 其实是倒推,先确定for的表达式 取好变量名
8.5 二进制文件
- 创建
多加一个b
f = open(r"d:\b.txt","ab") # 可写的、追加模式的二进制文件对象
f = open(r"d:\b.txt","wb") # 可写的、重写模式的二进制文件对象
f = open(r"d:\b.txt","rb") # 可读的二进制文件对象
-
写入、读取、关闭
一模一样
writelines(s) 写入文件 但是不添加换行符
# 拷贝一个已有的文件
with open("aa.gif","rb") as f:
with open("aa_copy.gif","wb") as w:
for line in f.readlines():
w.wirte(line)
print ("图片拷贝完成!")
seek()
操作字节,控制当前指针的位置
seek(0) # 文件返回最开始的位置
tell(): 返回文件指针当前位置
print(tell())
truncate() 删除
8.6 使用pickle序列化
把对象的数据形成一个序列,才能实现传输
import pickle
pickle.dump(a1,f) # 存
b1 = pickle.load(f) # 取
# 存的时候是啥顺序 取的时候就是啥顺序
8.6 csv文件的读取、写入
所有值都是字符串,用逗号分割
#测试 csv文件读写
import csv
with open("dd.csv","r") as f:
a_csv = csv.reader(f)
# print(list(a_csv))
# 注释是为了下面的程序能正常运行,
# 因为reader里有个指针
for row in a_csv:
print(row)
# 写:csv.writer(f)
# csv.writerrow(["f",'18'])
8.7 一些模块
os调用操作系统文件和命令
import os
os.system("notepad.exe")
os.system("ping www.baidu.com")
os.system("regedit")
os.startfile(r"E:\Program Files (x86)\QQMusic\QQMusic.exe")
# windows下 用的少一些
import os
# 获取文件和文件夹相关信息
print(os.name) #windows->nt linux和unix->posix
print(os.sep) #windows->\ linux和unix->/
print(repr(os.linesep)) #windows->\r\n linux-->\n\
print(os.stat("file.py"))
import os
# 关于工作目录的操作
print(os.getcwd())
# 改变当前的工作目录为:d:盘根目录
os.chdir("d:")
os.mkdir("书籍")
import os
# 创建(多级)目录、删除
os.mkdir("书籍")
# 相对路径都是相对于当前的工作目录
os.rmdir("书籍")
# 创建多级目录
os.makedirs("电影/港台/周星驰")
os.removedirs("电影/港台/周星驰") # 只能删除空目录
os.makedirs("../音乐/香港/刘德华") # ../指的是上一级目录
os.rename("电影","movie") # 旧名,新名
dirs = os.listdir("movie")
print(dirs)
path模块
#测试os.path中关于目录、路径的操作
import os
import os.path
# from os import path
# 写成这样的话 后面就可以写成path.xxx
############判断:绝对路径、是否目录、是否文件、文件是否存在#############
print(os.path.isabs("d:/a.txt")) # 是不是绝对路径 #True
print(os.path.isdir("d:/a.txt")) # 是不是目录 #False
print(os.path.isfile("d:/a.txt")) #True
print(os.path.exists("d:/a.txt")) # 是否存在
##############获得文件基本信息################
print(os.path.getsize("b.txt"))
print(os.path.abspath("b.txt"))
print(os.path.dirname("d:/a.txt"))
print(os.path.getctime("b.txt")) # 创建时间
print(os.path.getatime("b.txt")) # 访问时间
print(os.path.getmtime("b.txt")) # 修改时间
##############对路径的操作#####################
path = os.path.abspath("b.txt")
print(os.path.split(path)) # 切割 第一个元组目录 第二个元组文件名
print(os.path.splitext(path)) # 切割 分为扩展名前 扩展名
print(os.path.join("aa","bb","cc")) # 连接
# 获得当前目录下所有py文件 并输出文件名
import os
path = os.getcwd()
file_list = os.listdir(path)
#列出子目录、子文件
for filename in file_list:
if filename.endswith("py"):
print(filename,end="\t")
print("########################")
# 推导式法
file_list2 = [filename for filename in os.listdir(path) if filename.endswith("py") ]
for f in file_list2:
print(f,end="\t")
walk()方法
# 递归遍历所有子目录和子文件
import os
all_files = []
path = os.getcwd()
list_files = os.walk(path)
# 返回三个对象
for dirpath,dirnames,filenames in list_files:
for dir in dirnames:
all_files.append(os.path.join(dirpath,dir))
for file in filenames:
all_files.append(os.path.join(dirpath,file))
#打印所有的子目录和子文件
for file in all_files:
print(file)
shutil模块
文件、文件夹的拷贝、压缩、解压、删除
import shutil
import zipfile
shutil.copyfile("1.txt","1_copy.txt")
# 把 港台 文件夹里的拷贝到 电影 文件夹里
# 只有"电影"目录不存在时才能正常拷贝
shutil.copytree("movie/港台","电影")
# 忽略不需要的文件,这些扩展名的文件不要拷
shutil.copytree("movie/港台","电影",ignore=shutil.ignore_patterns("*.txt","*.html"))
import shutil
import zipfile
# 压缩 make_archive()
# 第一个参数:压缩后的文件所在的位置
# 第二个参数:压缩格式
# 第三个参数:待压缩文件所在的位置
shutil.make_archive("电影/hh","zip","movie/港台")
# 更简单的:压缩后的文件及所在的位置
z1 = zipfile.ZipFile("d:/a.zip","w")
z1.write("1.txt")
z1.write("1_copy.txt")
z1.close()
z2 = zipfile.ZipFile("d:/a.zip","r")
# 解压
z2.extractall("电影")
z2.close()
8.8 递归算法
包含:
- 递归头:什么时候不调用(递归的结束条件)
- 递归体
# 递归计算阶乘
def factorial(n):
if n==1:
return n
else:
return n*factorial(n-1)
print(factorial(5))
# 树结构
# 递归打印所有目录和文件
import os
allfiles = []
def getAllFiles(path,level):
childFiles = os.listdir(path)
for file in childFiles:
# print(file) # 这个仅是文件名
filepath = os.path.join(path,file)
if os.path.isdir(filepath) :
getAllFiles(filepath,level+1)
# 不能这样,因为这样直接打印是倒着的
# print("\t"*level+filepath)
# append的方法 在列表末尾添加新对象
allfiles.append("\t"*level+filepath)
getAllFiles("test_os",0)
for f in reversed(allfiles):
print(f)