分享

Python学习笔记 | 办公自动化基础之文件和文件夹操作

 网摘文苑 2022-12-09 发布于新疆

利用python实现办公自动化的基础就是管理磁盘文件和文件夹,如文件和文件夹的新建、删除、遍历查找等等,使用到的模块有os、shutil、golb、pathlib等。内容虽然简单,但是有些关键点也很容易出错,在这里做一下记录。

文章图片1

一、os模块

系统os模块提供了访问操作系统底层的接口,通过模块众多的方法可以实现对文件和文件夹的基础管理。os模块的方法如下:(前面有★符号的表示是经常使用的方法)

方法名

作 用

★os.listdir

列出指定目录下的所有子目录和文件(不向下遍历)

★os.scandir

扫描指定目录下的所有子目录和文件(不向下遍历)

★os.walk

生成目录树下的所有文件名(遍历所有目录)

★os.getcwd

获取当前工作目录

★os.chdir

改变目录(切换路径)

os.mkdir/makedirs

创建目录/创建多层目录(如:一次性创建a\b\c\d)

os.rmdir/removedirs

删除目录/删除多层目录

os.remove

删除文件

os.rename

重命名文件

★os.path.abspath

获取当前目录的绝对路径

★os.path.basename

获取指定路径中的基本名称(去掉路径)

★os.path.dirname

获取指定路径中的基本路径(去掉文件名)

★os.path.join

将给定的几个基本路径组合成一个路径

★os.path.split

将路径分割成路径和文件名两部分(dirname,basename)

os.path.splitext

将路径分割成路径+文件名(不含扩展名)和扩展名两部分

os.path.getatime

os.path.getctime

os.path.getmtime

获取文件或目录的最近访问、创建和修改时间,返回值是时间戳

os.path.getsize

获取文件尺寸

★os.path.exists

判断路径是否存在

os.path.isabs

判断是否为绝对路径

★os.path.isdir

判断是否为目录

★os.path.isfile

判断是否为文件

下面针对os模块的几个重要方法进行基本讲解:

1、os.listdir方法

os.listdir方法没有多余参数和属性,把子目录名称和文件名称统一放到一个列表里(目录和文件名称里均不含路径信息),使用时需要自行判断列表元素是目录还是文件。os.listdir方法比较简单直接,但是用起来比较顺手。演示代码如下:

import os# 列出当前目录下的所有子目录和文件result = os.listdir('./')# 查看listdir方法的返回值类型print('返回值类型:', type(result))# 查看返回结果for item in result: if os.path.isdir(item): print(item, '目录') else: print(item, '文件')输出结果:返回值类型: <class 'list'>test 目录test.py 文件搜索文件和文件夹.py 文件递归遍历目录.py 文件

2、os.scandir方法

os.scandir是Python官方推荐的方法,返回值是一个迭代器,里面的元素是os.DirEntry对象,该对象有两个属性:path和name,path属性中包含路径信息,name属性中不包含路径路径信息。演示代码如下:

import os# 扫描当前目录下的所有子目录和文件result = os.scandir('./')# 查看scandir的返回值类型,结果是迭代器print(type(result))# 使用循环遍历输出scandir的结果,有两个属性:path和name# path属性中包含路径,name属性中不包含路径,只有目录或文件名for item in result:    print(item.path, '\t', item.name)输出结果:<class 'nt.ScandirIterator'>./test 	 test./test.py 	 test.py./搜索文件和文件夹.py 	 搜索文件和文件夹.py./递归遍历目录.py 	 递归遍历目录.py

3、os.walk方法

os.walk方法自动遍历指定目录,包括遍历每层的子目录,返回值是一个生成器。它有四个参数:

  • top:指定的顶层目录
  • topdown:可选,为True时,则自上而下,而为False时,则自下而上
  • onerror:可选,是一个函数,OSError实例
  • followlinks:可选,通过软链接访问目录

演示代码如下:

import os# 遍历指定目录result = os.walk('./')# 查看返回类型是生成器print('返回值类型:', type(result))# 遍历输出for item in result: print('当前目录:', item[0]) print('包含目录:', end='') for i in item[1]: print(i, end=',') print() print('包含文件:', end='') for j in item[2]: print(j, end=',') print()输出结果:返回值类型: <class 'generator'>当前目录: ./包含目录:test,包含文件:test.py,搜索文件和文件夹.py,递归遍历目录.py,当前目录: ./test包含目录:包含文件:

4、os.path.abspath和os.path.join方法

os.path.abspath方法是获取当前目录的绝对路径,os.path.join方法用来将几个子目录名连接成一个完整路径。为什么要将这两个方法放在一起说呢?因为我在分析和学习pygame包自带的一个游戏代码时,发现了官方写代码的方式,全都是考虑了跨平台运行问题。

首先,官方程序的第一行就是#!/usr/bin/env python,这行代码在windows操作系统里运行时会当成注释忽略,而在linux系统里是指定解释器位置,避免程序拿到linux系统运行时出错,这就是考虑了跨平台问题。

然后,再说这两个方法。如果我们在写代码时把路径写成了windows系统的绝对路径,如:d:\python练习\飞机大战,那么你的程序拿到linux系统下是一定运行不起来的,没处去找这个路径,linux系统干脆就不分CDE盘。这时就可以使用这两个方法来解决路径跨平台问题,演示代码如下:

import osmain_dir = os.path.split(os.path.abspath(__file__))[0]file = os.path.join(main_dir, 'data', 'play.py')print(file)输出结果:D:\python练习\办公自动化\data\play.py

代码分析:首先获取当前文件所在位置的绝对路径,__file__表示当前文件,通过切割路径得到主路径;然后使用os.path.join方法,将主路径、子目录和文件名连接成最后想要的完整路径。这些代码里面没有出现任何操作系统的路径格式,这样os.path.abspath方法得到就是当前系统系统的路径格式,join方法同样按照当前操作系统规则进行连接,所以确保跨平台不会出现路径出错问题。

5、其它常用方法

演示代码如下:

import osprint(os.path.basename(r'd:\python练习\飞机大战\plane_main.py'))输出结果:plane_main.pyprint(os.path.dirname(r'd:\python练习\飞机大战\plane_main.py'))输出结果:d:\python练习\飞机大战print(os.path.join(os.getcwd(), 'test'))输出结果:D:\python练习\办公自动化\testpath1 = os.path.split(r'd:\python练习\飞机大战\plane_main.py')print(path1[0], '\t', path1[1])输出结果:d:\python练习\飞机大战 plane_main.pypath2 = os.path.splitext(r'd:\python练习\飞机大战\plane_main.py')print(path2[0], '\t', path2[1])输出结果:d:\python练习\飞机大战\plane_main .py

6、综合实例

下面用一个综合实例来演示os模块的主要方法的使用,这个程序不使用os提供的现成遍历函数walk,而是自己编写递归函数,来遍历获取指定目录下的所有文件,旨在深刻理解os模块各个方法的使用。
难点:递归函数从底层目录返回上级目录时,路径非常容易出错,造成返回结果不正常。
解决办法:在每层目录获取到包含的子目录列表时,直接把子目录转换成绝对路径形式再追加到目录列表里。这样在遍历完底层目录返回后,重新获得的路径是绝对路径,确保不出问题。

代码如下:

import os# 递归函数def get_allfile(path):		# 定义全局变量    global all_list    # 创建用于包含子目录的列表,初始值为空    all_dirs = []    all_files = []    # 切换到指定目录,这是向出口靠近的条件    os.chdir(path)    # 遍历指定目录本层的所有子目录和文件    for file in os.listdir(path):        if os.path.isfile(file):            # 如果是文件就直接追加到当前文件列表中            all_files.append(file)        else:            # 关键:如果是目录,则把该子目录的绝对路径追加到子目录列表中,防止递归往回返时路径出错            all_dirs.append(os.path.abspath(file))    # 将当前层目录名、包含的所有子目录和文件以元组形式追加到公共变量all_list列表中    all_list.append((path, all_dirs, all_files))    # 如果子目录列表不是空的,说明里面还有子目录,则调用本身继续遍历子目录,否则返回。    if len(all_dirs):        for file in all_dirs:        		# 调用本身,参数是子目录名            get_allfile(file)    else:        # 如果不包含子目录,则返回,这是递归函数的出口。        return    return all_list# 定义一个所有文件的空列表,在递归函数里向该列表里追加遍历到的文件名all_list = []# 调用递归函数遍历指定目录result = get_allfile(r'd:\python练习\飞机大战')# 循环遍历返回值列表,每个列表元素都是一个三元组for top_dir, subdir, file in result:    print('当前目录:', top_dir)    print('包含目录:')    for i in subdir:        print(i, '\t')    print()    print('包含文件:')    for j in file:        print(j, '\t')    print()输出结果:(未列出全部输出结果)当前目录: d:\python练习\飞机大战包含目录:d:\python练习\飞机大战\build 	d:\python练习\飞机大战\dist 	d:\python练习\飞机大战\images 	d:\python练习\飞机大战\sound 	d:\python练习\飞机大战\__pycache__ 	包含文件:plane_main.exe 	plane_main.py 	plane_main.spec 	plane_sprites.py 	score 	test.py 	飞机大战.py 	飞机大战V2.py 	飞机大战V3.py 	飞机大战V4.py 	

二、glob模块

glob模块非常简单,用来查找符合特定规则的目录和文件,返回值是一个列表,主要用作补充和辅助os模块。该模块最大的特点就是支持通配符,因此在查找时就显得非常灵活。

1、通配符

  • *:匹配0个或多个字符
  • **:匹配所有文件、目录、子目录和子目录里的文件
  • ?:匹配一个字符
  • []:匹配指定范围内的字符,如[0-9]匹配数字,[a-z]匹配小写字母

2、三个方法

  • glob.glob方法返回符合匹配条件的所有文件的路径,参数recursive表示递归调用,与特殊通配符“**”一同使用,返回值是列表。
  • glob.iglob方法:跟glob.glob方法一样,返回值是迭代器。
  • glob.escape方法:忽略所有特殊字符的通配符含义

glob模块演示代码如下:

import glob# 输出指定目录下的所有py文件print(glob.glob(r'd:\python练习\飞机大战\*.py'))输出结果:['d:\\python练习\\飞机大战\\plane_main.py', 'd:\\python练习\\飞机大战\\plane_sprites.py', 'd:\\python练习\\飞机大战\\test.py']# 输出所有t开头的py文件print(glob.glob(r'd:\python练习\飞机大战\t*.py'))输出结果:['d:\\python练习\\飞机大战\\test.py']# 输出当前文件夹下文件名由一个字母构成的py文件print(glob.glob('./?.py'))输出结果:['.\\t.py']# 输出所有文件名后面是数字1的py文件print(glob.glob('./*[1].py'))输出结果:['.\\t1.p# 输出当前文件夹下的所有目录和文件,不向下遍历print(glob.glob('./**'))输出结果:['.\\t.py', '.\\t1.py', '.\\test', '.\\test.py', '.\\搜索文件和文件夹.py', '.\\递归遍历目录.py']# 输出当前文件夹下的所有目录和文件,并遍历所有子文件夹print(glob.glob('./**',recursive=True))输出结果:['.\\', '.\\t.py', '.\\t1.py', '.\\test', '.\\test\\find_file.py', '.\\test.py', '.\\搜索文件和文件夹.py', '.\\递归遍历目录.py']

三、shutil模块

shutil是shell until的缩写,同样是作为os模块的补充,提供了复制、移动、删除、压缩、解压等操作。但是,shutil 模块对压缩包的处理是调用 ZipFile 和 TarFile这两个模块来进行的,跟zipfile模块的压缩解压缩是不同的。

常用方法:

  • shutil.copy:复制文件
  • shutil.copytree:复制文件夹
  • shutil.move:移动文件或文件夹
  • shutil.rmtree:删除文件夹
  • zipobj.write:创建一个压缩包
  • zipobj.namelist:读取压缩包中的文件信息
  • zipobj.extract:解压缩单个文件
  • zipobj.extractall:解压缩所有文件

shutil模块使用简单,不再赘述。


四、pathlib模块

pathlib是从python3开始推出的跟os模块功能重叠的内置模块,能够完全替代os.path。Python官网中这样说:“对于字符串的低级路径操作,也可以使用该os.path模块”,这足以证明pathlib有着os.path不能比拟的优点。

在Python 3.4之后,pathlib成为标准库模块,其使用面向对象的编程方式来表示文件系统路径,丰富了路径处理的方法。

1、pathlib模块的优势

  • pathlib实现统一管理,解决了传统操作导入模块不统一问题;
  • pathlib使得在不同操作系统之间切换非常简单;
  • pathlib是面向对象的,路径处理更灵活方便,解决了传统路径和字符串并不等价的问题;
  • pathlib简化了很多操作,简单易用。

2、pathlib模块的主要属性和方法

pathlib模块有一个重要的类——Path,基本上对文件和文件夹的所有操作都是使用Paht的方法和属性完成的,因此重点介绍Paht类的属性和方法的使用。

属性

作 用

Path.name

返回完整文件名(包含后缀),如果是目录则返回目录名

Path.stem

返回文件名(不包含后缀),如果是目录则返回目录名

Path.suffix

返回文件后缀

Path.parents

返回所有上级目录的列表

Path.parts

返回分割路径后的元组

Path.root

返回路径的根目录

Path.driver

返回驱动器名称

方法

作 用

Path.resolve()

获得绝对路径

Path.cwd()

获得当前工作目录

Path.home()

返回电脑的用户目录

Path.stat()

获得文件属性

Path.chmod()

修改文件权限和时间戳

Path.mkdir()

创建目录

Path.rmdir()

删除目录

Path.unlink()

删除一个文件

Path.rename()

文件或文件夹重命名,如果路径不同,会移动并重新命名

Path.replace()

文件或文件夹替换,如果路径不同,会移动并重新命名,如果存在,则破坏现有目标。

Path.open()

打开文件(支持with)

Path.read_bytes()

以字节格式读取文件

Path.read_text()

以文本格式读取文件

Path.write_bytes()

以字节格式写入文件

Path.write_text()

以文本格式写入文件

Path.iterdir()

查找所有子目录和文件,不递归遍历子目录,没有参数

Path.glob()

查找所有文件,不递归遍历子目录,必须指定参数

Path.rglob()

递归遍历目录下的所有子目录和文件,必须指定参数

Path.joinpath()

拼接路径

Path.exists()

判断文件或目录是否存在

Path.is_dir()

判断是否为目录

Path.is_file()

判断是否为文件

Path.is_symlink()

判断是否为符号链接

3、代码演示

from pathlib import Path# 创建pathlib模块Path类对象path=Path(r'd:\python练习\飞机大战')print(path.cwd())  # 输出当前目录print(path.home())  # 输出电脑的用户目录输出结果:D:\python练习\办公自动化C:\Users\Administrator.User-2022BIVGGU# 使用Path类拼接路径path1=Path(path.cwd(),'test')path2=Path.joinpath(path.cwd(),'test')print(path1)print(path2)输出结果:D:\python练习\办公自动化\testD:\python练习\办公自动化\testpath=Path.cwd()print(path.name)  # 输出当前路径对象的目录名print(path.stem)  # 输出当前路径对象的目录名print(Path(r'd:\python练习\飞机大战').name)  # 输出指定目录的当前目录名输出结果:办公自动化办公自动化飞机大战# 查找当前目录下的所有py文件,不递归遍历子目录resulte = path.glob('*.py')  # 必须指定参数for item in resulte:    # 分别输出完整文件名,文件名和后缀    print(item.name, item.stem, item.suffix, sep='  |  ')输出结果:t.py  |  t  |  .pyt1.py  |  t1  |  .pytest.py  |  test  |  .py搜索文件和文件夹.py  |  搜索文件和文件夹  |  .py递归遍历目录.py  |  递归遍历目录  |  .py# 遍历当前目录下的所有子目录和文件,不递归遍历子目录resulte = path.iterdir()  # 不能带参数for item in resulte:    # 分别输出完整文件名,文件名和后缀    print(item.name, item.stem, item.suffix, sep='  |  ')输出结果:t.py  |  t  |  .pyt1.py  |  t1  |  .pytest  |  test  |  test.py  |  test  |  .py搜索文件和文件夹.py  |  搜索文件和文件夹  |  .py递归遍历目录.py  |  递归遍历目录  |  .py# 遍历当前目录下的所有子目录和文件resulte = path.rglob('*')  # 必须指定参数for item in resulte:    # 如果是目录,则输出该目录的绝对路径、子目录名和“子目录”三个文字    if item.is_dir():        print(item.resolve(), item.name, '子目录', sep='  |  ')    # 如果是文件,则输出该文件所在目录的绝对路径、文件名和“文件”两个文字    elif item.is_file():        print(item.resolve(), item.name, '文件', sep='  |  ')输出结果:D:\python练习\办公自动化\t.py  |  t.py  |  文件D:\python练习\办公自动化\t1.py  |  t1.py  |  文件D:\python练习\办公自动化\test  |  test  |  子目录D:\python练习\办公自动化\test.py  |  test.py  |  文件D:\python练习\办公自动化\搜索文件和文件夹.py  |  搜索文件和文件夹.py  |  文件D:\python练习\办公自动化\递归遍历目录.py  |  递归遍历目录.py  |  文件D:\python练习\办公自动化\test\find_file.py  |  find_file.py  |  文件

综合实例代码:在输入的路径里查找包含输入的关键字的所有目录和文件

from pathlib import Path# 循环检测输入的路径是否为正确格式并且路径存在while True: top_path = input('请输入搜索起始路径:') # 创建pathlib模块的Path类对象,参数中将搜索路径去掉首尾空格 top_path = Path(top_path.strip()) # 如果输入路径格式正确并且该路径存在,则中断循环并向下指向 if top_path.exists() and top_path.is_dir(): break else: print('输入的路径有误,请重新输入!')search = input('请输入搜索关键字:')result = list(top_path.rglob(f'*{search}*'))if result: result_dir = [] result_file = [] for i in result: if i.is_dir(): result_dir.append(i) if i.is_file(): result_file.append(i) if result_dir: print(f'找到了跟“{search}”相符合的文件夹:') for i in result_dir: print(i) print('-'*30) if result_file: print(f'找到了跟“{search}”相符合的文件:') for i in result_file: print(i)else: print(f'抱歉!在路径“{top_path}”里,没有搜索到跟“{search}'符合的文件和文件夹!')输出结果:请输入搜索起始路径:d:\python练习\办公自动化请输入搜索关键字:t找到了跟“t”相符合的文件夹:d:\python练习\办公自动化\test------------------------------找到了跟“t”相符合的文件:d:\python练习\办公自动化\t.pyd:\python练习\办公自动化\t1.pyd:\python练习\办公自动化\test.py

五、tempfile模块

tempfile模块的功能是创建临时文件和临时文件夹,程序运行结束后,创建的临时文件和文件夹会自动删除,方便临时转储文件和记录信息。

1、tempfile模块的应用场景

在大型数据处理项目中,有的处理结果是不需要向用户最终展示的,但是它们的应用又是贯穿项目始终的,在这种情况下,我们就需要使用tempfile模块来解决这种问题。

2、tempfile模块的类

tempfile模块供了四个高级类(自动清除关闭的文件)和两个需要手动清理的方法:

  • TemporaryFile类:用于读写临时文件,并且保证临时文件的隐藏性,默认的文件打开模式是w+b。
  • NamedTemporaryFile类:与Temporaryfile类操作类似,但是增加了对文件关闭后是否删除的判断,即delete参数,默认是True。
  • TemporaryDirectory类:安全地创建一个临时目录,返回的对象可用于上下文管理器使用。
  • SpooledTemporaryFile类:在Temporaryfile类基础上增加一个写入闸值Max_size,当数据没有达到max_size时,会暂存在内存中;当数据超过max_size设置的值后,数据会自动写入到临时文件里保存,默认Max_size为0。

3、tempfile模块的方法

  • gettempdir():以文本格式返回系统临时文件夹名
  • gettempdirb():以二进制格式返回系统临时文件夹名
  • gettempprefix():以文本格式返回临时文件名
  • gettempprefixb():以二进制格式返回临时文件名
  • mkstemp() 和 mkdtemp() :底层临时文件和文件夹创建,需要手动清理的方法

4、演示代码

import tempfile# 输出系统的临时文件夹路径print('系统的临时文件夹路径是:', tempfile.gettempdir())# 在当前文件夹里创建临时文件夹tempdir = tempfile.TemporaryDirectory(dir='./')print('新建的临时文件夹路径是:', tempdir.name)# 清除临时文件夹tempdir.cleanup()# 使用上下文方式管理临时文件夹,不用调用cleanup方法手动清除with tempfile.TemporaryDirectory(dir='./') as temp_dir:    # 使用上下文with模式在新建的临时文件夹中新建临时文件    with tempfile.TemporaryFile() as temp_file:        # 写入到临时文件中的信息必须是字节格式        temp_file.write(b'hello world!')        # 将指针移动到开始处读取临时文件内容并解码输出        temp_file.seek(0)        msg = temp_file.read()        print(msg.decode())输出结果:系统的临时文件夹路径是: C:\Users\ADMINI~1.USE\AppData\Local\Temp新建的临时文件夹路径是: ./tmph5rj1at5hello world!

六、zipfile模块

zipfile是压缩和解压缩模块,虽然叫zipfile,但是除了zip之外,rar,war,jar这些压缩(或者打包)文件格式也都可以处理。

1、常用方法

  • ZipFile.getinfo:获取zip文档内指定文件的信息
  • ZipFile.infolist:获取zip文档内所有文件的信息
  • ZipFile.namelist:获取zip文档内所有文件的名称列表。
  • ZipFile.extractall:将zip文档内的指定文件解压到当前目录,参数:member 要解压的文件名称,path解析文件保存的文件夹,pwd 解压密码
  • ZipFile.printdir:将zip文档内的信息打印到控制台上
  • ZipFile.setpassword:设置zip文档的密码
  • ZipFile.read:获取zip文档内指定文件的二进制数据
  • ZipFile.write:将指定文件添加到zip文档中
  • ZipFile.writestr:支持将二进制数据直接写入到压缩文档

2、演示代码

import zipfilefrom pathlib import Path# 创建路径对象path=Path('./')# 获取当前文件夹下的所有py文件files=path.glob('*.py')# 创建并打开zippy.zip压缩文件with zipfile.ZipFile('zippy.zip','w') as zipobj: # 循环将所有py文件添加到压缩文件中 for file in files: zipobj.write(file) print(f'文件{file}被添加到zippy.zip压缩文件中...') # 给压缩文件设置密码 zipobj.setpassword(b'123') print('压缩完毕!')输出结果:文件t.py被添加到zippy.zip压缩文件中...文件t1.py被添加到zippy.zip压缩文件中...文件test.py被添加到zippy.zip压缩文件中...文件搜索文件和文件夹.py被添加到zippy.zip压缩文件中...文件递归遍历目录.py被添加到zippy.zip压缩文件中...压缩完毕!

注:经过测试,添加的密码不起作用,需要深入研究。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多