Python的学习心得和知识总结(九) 您所在的位置:网站首页 python文本文件综合应用 Python的学习心得和知识总结(九)

Python的学习心得和知识总结(九)

2024-05-27 04:05| 来源: 网络整理| 查看: 265

一个完整的程序都是包括 数据的读取和存储,在实际开发中 经常性的需要从外存(硬盘、光盘和U盘等)里面读取数据,或者将程序执行过程中产生的中间数据存放在文件(日志等),以及将运算结果进行持久化保存等。这些过程都离不开与文件打交道!

文章目录 文本文件和二进制文件Python文件操作的模块Python文件操作的方法创建文件对象open()文本文件的写入处理文件编码及乱码解决关闭文件对象close()文本文件的读取操作enumerate()函数和推导式生成列表 二进制文件读写操作 文件对象的常用属性(和方法)文件对象的属性文件对象的打开模式文件对象的常用方法 -------------------------------模块的使用-------------------------------使用pickle模块进行序列化CSV文件的操作os和os.path模块os模块的文件目录操作方法os.path模块提供目录路径相关的操作os.walk()方法来递归遍历文件和目录 shutil模块

文本文件和二进制文件

根据文件中数据的组织形式,可以把文件分为文本文件和二进制文件:

文本文件:存储的是普通的 “字符”文本,默认的字符集为Unicode(2字节表示一个字符 65536种)。如下:(我们使用notepad或者记事本写的文件,下面我们可以看到它的字符集是utf-8)在这里插入图片描述二进制文件:数据内容用“字节”来存储的,需要使用专门的格式软件来解码打开。如:mp3音频、mp4视频以及doc文档等(否则乱码)在这里插入图片描述 Python文件操作的模块

在Python的标准库里面,有一些与文件操作相关的模块 如下是简要的描述:

模块名称简要说明I/O模块文件流的输入输出操作OS模块基于操作系统功能,包含文件操作Glob模块查找符合特定规则的文件路径名Fnmatch模块使用模式来匹配文件路径名Filecmp模块用于文件的比较Cvs模块使用于csv文件的处理Pickle和cPickle模块用于序列化和反序列化处理xml包用于xml数据处理bz2、gzip、zipfile、zlib和tarfile用于处理压缩和解压缩文件(分别对应于不同的算法) Python文件操作的方法 创建文件对象open()

在Python里面一切皆对象,open()创建出来的也是一个文件对象。其语法格式如下:

open(filename[,打开方式])

若是只是文件名,则代表当前目录下面的文件。(文件名可以使用绝对路径来指定)我们都知道在输入一个文件路径的时候,会使用到大量的 \ 。(这玩意儿在字符串里面整不好成了转义字符)因此为了减少 \的大量使用,我们使用原始字符串(就是路径的前面加上一个r)示例如下:

f=open(r"E:\Tsinghua_University\Python_Study\myexception3\venv\test.py","a")

文件的打开方式有下面几种:

文件模式详细描述rreadwwrite(文件不存在则创建;存在则重写新内容)aappend (文件不存在则创建;存在则追加写新内容)b二进制模式(可以与其他模式组合使用)+读写模式(可以与其他模式组合使用)

上面的文本文件和二进制文件对象的创建:若是没有使用 b模式,则默认为创建文本文件对象(处理的基本单元是 字符);否则为二进制文件对象(处理的基本单元是 字节)

文本文件的写入处理

文件文件的写入操作三部曲:

创建文件对象数据写入关闭这个文件对象(关闭解释器和OS打开的一些资源)

通常写入数据的时候有两个方法:write()和writelines()

# coding=utf-8 fp=open(r"test1.txt","a",encoding="utf-8") str1="Tsinghua\nUniversity\n" str2="清华\n大学\n" fp.write(str1) fp.write(str2) fp.close() #write()是把字符串写入到文件里面(若是多行,则需要换行符 \n)。它是不能够写入一个列表的, #否则:TypeError: write() argument must be str, not list

而writelines()是支持写一个字符串列表到一个文件里面:

# coding=utf-8 fp=open(r"test1.txt","a",encoding="utf-8") str1="Tsinghua\nUniversity\n" strlist=["清华","大学\n","浙江","大学"] fp.write(str1) fp.writelines(strlist) fp.close()

在这里插入图片描述 但是需要注意的是:writelines()函数在写入列表的时候,没有自动添加换行符(需要我们自己加)。

文件编码及乱码解决

下面我们来看一个简单的例子:

# coding=utf-8 fp=open(r"test1.txt","a") str1="Tsinghua\nUniversity\n" str2="清华\n大学\n" fp.write(str1) fp.write(str2) fp.close()

执行之后的结果如下: 在这里插入图片描述 我们的中文没有打印出来,显示却是乱码!

接下来我们稍微简单的介绍一下在计算机世界里面的几种字符集和编码:

ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

单字节即8位,且最高位现为0,也就是说使用了低7位(表示128个字符)。 在这里插入图片描述 这对于简单的English来说就足够用了,这点量跟博大精深的汉字 不能比 不能比! 如上图所示,对这个编码系统做个小结:

1、0到31表示:控制字符(如回车 退格 删除等) 2、32到126表示:可以借助于键盘输入并可以显示的字符。48到57代表十个阿拉伯数字;65到90是26个大写英文字母(每个加上32就是对应的小写字母)

ISO Latin-1字符集是Unicode字符集的一个子集,对应于IE4+中Unicode字符指令表的前256个条目。其中Unicode字符为双字节16位,可以表示任何一种语言符号(定长,两字节表示一个字符 65536个);而Latin-1字符集是单字节8位,只能够表示英文和西欧字符。详细内容还请看博客ISO Latin-1字符集。Unicode通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0就可以。但是这样用在英文类字符身上,是一种极大的资源浪费。于是产生了UTF-8(Unicode的具体实现):是变长编码。英文一个字节,汉字3个字节。

ISO Latin-1字符集是兼容ASCII的,增加了西欧小国的语言字符。

GB2312、GBK、GB18030字符集是兼容上面的ISO Latin-1字符集。这套系统是:英文一个字节,汉字2个字节。 也就是说从0到127就是ASCII的那些字符。GBK全称为 Chinese Internal Code Specification,即汉字内码扩展规范,于 1995 年制定。它主要是扩展了 GB2312,在它的基础上又加了更多的汉字,它一共收录了 21003 个汉字。GB18030 是现在最新的内码字集于 2000 年发布,并于 2001 年强制执行,包含了中国大部分少数民族的语言字符,收录汉字数超过 70000 余个。它主要采用单字节、双字节、四字节对字符编码,它是向下兼容 GB2312 和 GBK 的,虽然是我国的强制使用标准,但在实际生产中很少用到,用得最多的反而是 GBK 和 GB2312。

产生乱码(中文)的原因:编码和解码的字符集系统不一致。windows 操作系统默认的编码是 GBK,Linux 操作系统默认的编码是 UTF-8。当我们用 open()时,调用的是操作系统打开的文件,默认的编码是 GBK。

而上面之所以产生乱码,我们来看一下我们的文件编码的时候是用的哪一套系统? 在这里插入图片描述 然后我们点击这个FileEncoding,选择 GBK (进行编码切换)即可。 在这里插入图片描述 或者我们直接通过指定文件编码解决中文乱码问题:

# coding=utf-8 fp=open(r"test1.txt","a",encoding="utf-8") str1="Tsinghua\nUniversity\n" str2="清华\n大学\n" fp.write(str1) fp.write(str2) fp.close()

因为Python程序执行的时候默认使用Unicode编码,实际存储的时候有可能是utf-8 or GBK(由OS的系统调用决定的,就是写入文件时候的编码)。可是等我们打开这个文件的时候用的是UTF-8来解码的,于是出现乱码(后面我们解码切换成GBK编码就显示中文OK了)。而上面的代码在open里面就指定了写文件时的文件编码,后面再使用UTF-8来打开的时候就没事了。

关闭文件对象close()

我们前面也说了,归根到底 文件操作都是由OS来控制的,我们打开的文件对象必须要显式调用close()方法来关闭。

当调用close()的时候,首先会把缓冲区数据写入文件(或者可以直接调用flush()方法),然后关闭文件并释放文件对象。

可是当我们open一个文件对象并进行了操作,若是此时发生异常而导致后面的close()没有去执行。(导致了打开的文件对象没有关闭)于是这个时候就要去结合我们刚学的异常处理机制 finally或者with关键字来实现了。

# coding=utf-8 try: fp=open(r"test1.txt","a",encoding="utf-8") str1="Tsinghua\nUniversity\n" strlist=["清华","大学\n","浙江","大学"] fp.write(str1) fp.writelines(strlist) a=1/0 except BaseException as e: print("该异常的类型是:",type(e),";","该异常是:",e) finally: fp.close()

在这里插入图片描述 下面我们来看一下在Python里面更加常用的一种机制:with上下文管理:可以自动的管理上下文资源。(不论什么原因离开with块,都能够保证文件被正常的关闭。并且可以在代码块执行完成之后自动还原到进入该代码块是的现场)

# coding=utf-8 str1="Tsinghua\nUniversity\n" strlist=["清华","大学\n","浙江","大学"] with open(r"test1.txt","a",encoding="utf-8") as fp: fp.write(str1) fp.writelines(strlist)

这样使用起来确实更加简便!

文本文件的读取操作

文件读取一般使用到如下三个方法:

read([size]):从文件中读取size个字符,并作为结果返回。若是没有size传入,则读取整个文件。读取到文件末尾,会返回空字符串。(文本文件以字符为单位,一个汉字是一个字符)readline():读取一行内容作为结果返回。读取到文件末尾,会返回空字符串。readlines():文本文件中,每一行作为一个字符串存入到列表中,返回该列表。

OK,看一下下面的这些实例: 在这里插入图片描述 我们的文件内容如上所示:

#读取一个文件的前10个 字 符: #一次性将文件内容读到程序中:

在这里插入图片描述

#按行读取一个文件 #使用迭代器(每次返回一行)读取文本文件

在这里插入图片描述 之所以在程序里面使用end="",因为我们的文件里面已经有一个换行符了(上面的那个打印前10个字符也看到了)。

enumerate()函数和推导式生成列表

下面我们先看一下enumerate函数:

# coding=utf-8 with open(r"test1.txt","r",encoding="utf-8") as iterator_f: a=enumerate(iterator_f) print(a,type(a)) b=list(a) print(b)

结果如下所示: 在这里插入图片描述

操作文件每行内容前面都加上 行号 # coding=utf-8 with open(r"test1.txt","r",encoding="utf-8") as iterator_f: a=enumerate(iterator_f) print(a,type(a)) b=list(a) print(b) print(a) str=["*"+str(index)+" "+value for index,value in b] print(str) with open(r"test2.txt","a",encoding="utf-8") as fp: fp.writelines(str)

在这里插入图片描述 在这里插入图片描述

二进制文件读写操作

二进制文件的处理流程和文本文件的一样:

1、创建文件对象(需要指定二进制模式) 2、创建好之后就可以使用write()、read()实现文件的读写操作

下面我们就来看一个实例:

# 读取一个图片,然后实现该文件的拷贝

在这里插入图片描述 这是我们的一张图片,下面我们来利用Python的文件操作再复制一张:

# coding=utf-8 # rb模式是 创建一个可读的二进制文件对象 with open("Tsinghua.jpg","rb") as fr: with open("Tsinghua_Of_Copy.jpg","wb") as fw: for a_line_of_file in fr.readlines(): fw.write(a_line_of_file) print("文件拷贝完成!")

在这里插入图片描述

文件对象的常用属性(和方法)

文件对象封装了文件相关的操作,下面我们就来列举一下文件对象的常用属性和方法:

文件对象的属性 name:返回文件的名字mode:返回文件的打开模式closed:若是文件被关闭则返回true 文件对象的打开模式 r :读模式w : 写模式a :追加模式b :二进制模式(可以和其他模式结合)+ :读写模式(可以和其他模式结合) 文件对象的常用方法 read([size]):从文件中读取size个字符(文本文件)or 字节(二进制文件)的内容返回;没有size则读到尾(一次读完全部内容)readline():从文本文件中读取一行readlines():把文本文件中的每一行内容都作为独立的字符串对象 放到列表中返回write(str):将字符串内容写到文件中 (返回值表示写入的字符数)writelines(list):将字符串列表写入文本文件(不会自动添加换行符)tell():返回文件指针的当前位置(字节为单位 从0开始数,然后返回值是当前指向的字节值)truncate([size]):无论指针在什么位置,只保留指针前size个字节的内容。(其他全部删除);若是没有size,则该指针位置到文件末尾的内容全部删掉flush():把缓冲区的内容写入文件(并不关闭文件)close():把缓冲区内容写入文件,然后关闭文件 释放文件对象相关资源seek(offset[,whence]):把文件指针移动到新的位置,offset表示相对于whence的多少个的字节偏移量。offset为正则往后移动,否则则往前移动。whence的值:0 从文件头开始计算(默认);1 从当前位置开始计算;2 从文件尾部开始计算 在这里插入图片描述 更加详细的分析如下: 在这里插入图片描述 在这里插入图片描述 -------------------------------模块的使用------------------------------- 使用pickle模块进行序列化

在Python里面,一切皆对象 对象在本质上就是一个“存储数据的内存块”。可是有时候我们需要将这个“内存块上的数据”保存到硬盘之上 or 借助于网络传送到其他的地方。这个时候 就要使用“对象的序列化和反序列化”,那么什么是序列化和反序列化呢?

序列化:将对象转化成 “串行化”的数据形式,保存到硬盘之上 or 借助于网络传送到其他的地方 反序列化:反过程 将读取到的“串行化”数据 转化成对象

具体的方法使用如下:

# 序列化 pickle.dump(obj,file) #obj是被序列化的对象,file是存储的文件 # 反序列化 pickle.load(file) #从file里面读取数据,然后反序列化成对象

在这里插入图片描述 在这里插入图片描述 注:此时的str对象 和 str1对象是两个完全不同的对象。(仅仅是内容一样而已)

CSV文件的操作

CSV:(Comma Separated Values)逗号分隔符文本格式 常用于 数据交换、Excel文件和数据库数据的导出导入等;不同于Excel文件的是,CSV文件有:

1、值没有类型,所有值都是字符串 2、不能指定字体 颜色等样式 3、不能指定单元格的 宽和高,不能合并单元格 4、没有多个工作表 5、不能嵌入 图像图表等

CSV文件的操作使用的是Python标准库里面的csv模块,它提供了对于csv格式文件对象的 读写方法。

下面来看一下,我们有这么一个表格文件 内容如下: 在这里插入图片描述 我们把它转成CVS格式的文件如下: 在这里插入图片描述 下面我们首先看一下CSV文件的读取操作: 在这里插入图片描述 在这里插入图片描述 下面看一下往一个CSV里面写内容 (写入的内容是list对象): 在这里插入图片描述 在这里插入图片描述

os和os.path模块

os模块可以帮助我们直接对OS进行操作,即:可以直接调用OS的可执行程序、命令来对文件 目录来进行操作!(大家熟悉Linux开发的话,就相当于我们在C语言里面调用的system(cmd)来执行一个脚本or命令)

具体的实例如下:(调用一下Windows的程序等) 在这里插入图片描述 在这里插入图片描述 或者是打开我们的CMD,如下(被重定向到控制台): 在这里插入图片描述 OK,下面我们直接调用可执行的文件(提前得安装OK的!例如 QQ):

os.startfile(r"D:\360安全浏览器下载\Tencent\QQ\Bin\QQScLauncher.exe")

在这里插入图片描述

os模块的文件目录操作方法

除了之前学的文件对象操作来实现对文件内容的读写,我们还可以使用这里的os和os.path模块来实现文件和目录的操作。

os模块 文件操作方法:

方法描述remove(path)删除一个指定的文件rename(src,dest)重命名文件或者目录stat(path)返回文件的所有属性listdir(path)返回path目录下的文件和目录列表

os模块 目录操作方法:

方法描述mkdir(path)创建目录makedirs(path1/path2/- - -)创建多级目录rmdir(path)删除目录removedirs(path1/path2/- - -)删除多级目录getcwd()返回当前工作目录chdir(path)把path作为当前工作目录walk()遍历目录树sep()当前OS所使用的路径分隔符

在这里插入图片描述 注:相对路径都是相对于当前的工作目录而言的! 也就是说chdir之后,工作目录已经变了。对于某些删除操作,只有在不使用该目录的时候完成! 在这里插入图片描述 这个removedirs是只可以删除空的目录,若是目录下面有内容 则报错:OSError 此时我们想用listdir来返回当前目录下的文件和目录列表: 在这里插入图片描述

os.path模块提供目录路径相关的操作

在实际的操作中,掌握了一个确定而又准确的path 就可以完成很多的后续操作。而路径path又是一个操作的难点,因此Python为我们提供了关于路径的一些方法(路径判断、路径切分、路径连接和目录遍历等)如:

1、isabs(path):判断路径是否为绝对路径 2、isdir(path):路径是否为目录 3、isfile(path):路径是否为文件 4、exists(path):指定路径的文件是否存在 5、getsize(filename):得到文件大小 6、abspath(path):返回绝对路径 7、dirname ( p):返回目录的路径 8、getatime(filename):得到文件的最新访问时间 9、getctime(filename):得到文件的创建时间 10、getmtime(filkename):得到文件的最新修改时间 11、walk(top,func,arg):递归的方式遍历目录 12、join(path,*paths):连接多个路径 13、split(path):对该路径进行切分,最后以元组形式返回 14、splitext(path):从路径中分割得到文件的扩展名

在这里插入图片描述

#coding=utf-8 ''' Author :SongBaoBao Project :untitled filename:mypath.py currtime:2020/6/25--9:47 commpany:Tsinghua University mycsdnis:https://blog.csdn.net/weixin_43949535 yylolLPL:Royal Never Give Up ''' # 测试os.path模块的路径和目录操作 import os import time # import os.path from os import path currentpath=os.getcwd() print("当前的目录currentpath为:",currentpath) print("当前Python文件的绝对路径为:",path.abspath("mypath.py")) print("currentpath是不是绝对路径:",path.isabs(currentpath)) print("currentpath是不是目录路径:",path.isdir(currentpath)) print("currentpath是不是文件路径:",path.isfile(currentpath)) # 拼接当前Python文件的绝对路径 thisfilepath=path.join(currentpath,"mypath.py") print("当前的文件mypath.py是否存在:",path.exists(thisfilepath)) print("当前的文件mypath.py文件大小:",path.getsize(thisfilepath),"byte") print("当前Python文件的所在目录为:",path.dirname(thisfilepath)) # 当前Python文件的时间信息 print("当前文件的创建时间是:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(path.getctime(thisfilepath)))) print("当前文件的访问时间是:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(path.getatime(thisfilepath)))) print("当前文件的修改时间是:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(path.getmtime(thisfilepath))))

结果显示为:

E:\Tsinghua_University\Python_Study\untitled\venv\Scripts\python.exe E:/Tsinghua_University/Python_Study/untitled/venv/src/mypath.py 当前的目录currentpath为: E:\Tsinghua_University\Python_Study\untitled\venv\src 当前Python文件的绝对路径为: E:\Tsinghua_University\Python_Study\untitled\venv\src\mypath.py currentpath是不是绝对路径: True currentpath是不是目录路径: True currentpath是不是文件路径: False 当前的文件mypath.py是否存在: True 当前的文件mypath.py文件大小: 1444 byte 当前Python文件的所在目录为: E:\Tsinghua_University\Python_Study\untitled\venv\src 当前文件的创建时间是: 2020-06-25 09:45:55 当前文件的访问时间是: 2020-06-25 10:22:41 当前文件的修改时间是: 2020-06-25 10:22:41 Process finished with exit code 0

在这里插入图片描述 在这里插入图片描述 OK,下面我们来做一些练习: 在这里插入图片描述

os.walk()方法来递归遍历文件和目录

下面来看一个比较重要的方法:os.walk()来递归的遍历所有的文件:

os.walk() --------- 返回一个三个元素的tuple:(dirpath,dirnames,filenames) ------------------------------------------------- 一、该指定的目录路径 二、目录下的所有目录 三、目录下的所有文件

实例代码如下:(遍历src目录下的所有文件:) 在这里插入图片描述

#coding=utf-8 ''' Author :SongBaoBao Project :untitled FileName:mywalk.py Currtime:2020/6/25--13:40 Commpany:Tsinghua University MyCsdnIs:https://blog.csdn.net/weixin_43949535 MyLolLpl:Royal Never Give Up ''' # 测试walk方法来递归的遍历文件 import os from os import path curpath=os.getcwd() print(curpath) # 来遍历src目录 file_list_of_src=os.walk("../..") print(file_list_of_src) print("*"*127) i=0 for dirpath,dirnames,filenames in file_list_of_src: this_abspath=path.abspath(dirpath) print("\033[1;34m ","一个目录为:",format(dirpath,"


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有