本篇目录
一、文件及文件夹增删改查
1.1 常规操作
- 代码示例
import os # 显示系统默认路径分隔符:win10为'\\' os.sep >>> '/' # pwd命令:获取当前所在路径 os.getcwd() # win10:'E:\\code\\test' >>>'/root' # cd命令:修改工作路径,无返回值 # 不存在报错FileNotFoundError os.chdir("/home") # ls 命令 # 无参数:显示当前工作目录下文件列表 # 有参数:指定路径下的文件列表, # 不存在报错FileNotFoundError os.listdir() >>> ['sam', 'smith', 'base.py'] # mkdir命令:如果已存在,报错FileExistsError os.mkdir("duke") import shutil # 复制文件:当前文件夹内 shutil.copy("base.py","base_backup.py") >>> 'base_backup.py' # 复制文件到文件夹内:可以写绝对路径,相对路径 shutil.copy("base.py","duke") >>> 'duke/base.py' # 复制文件夹:第二个为路径,若不存在会递归创建 # 若存在,则报错FileExistsError shutil.copytree("duke","duke_backup") >>> 'duke_backup' # move命令:移动和重命名,同父文件夹则重命名,文件和文件夹都可以 shutil.move("base_backup.py", "base_back.py") >>> 'base_back.py' # rm -rf 目录:删除目录 shutil.rmtree("duke_backup") # 删除文件 os.remove("base_back.py")
1.2 权限操作
- 代码示例
import os os.listdir() >>> ['123.py'] # 查看文件权限:W_OK可写、R_OK可读,X_OK可执行 os.access('123.py', os.R_OK) >>> True # 获取文件所有者uid:在文件/etc/password内 os.stat('123.py').st_uid >>> 0 # 获取文件所有组gid:在文件/etc/password内 os.stat('123.py').st_gid >>> 0 # 修改权限:十进制不能以0开头 os.chmod('123.py', 0o700)
二、遍历文件夹
- os.walk实现
# os.walk()返回的是生成器: 可以写相对路径:"."、"duke",与下效果同 for dirpath,dirnames,filenames in os.walk("/home/duke"): print(dirpath) print(dirnames) print(filenames) # 以上为第一轮遍历: # 当前遍历的文件夹名 /home/duke # 子文件夹名列表 ['base'] # 子文件名列表 ['base.py'] # 同第一个遍历 /home/duke/base ['subdir'] ['a.py', 'b.py'] # 同第一个遍历 /home/duke/base/subdir [] []
- 定制化遍历文件夹
import os import re def is_file_match(filename, patterns): # 遍历规则 for pattern in patterns: # 匹配文件名和规则:如果不匹配则为[] if re.findall(pattern, filename): return True return False # 此为一个生成器:因为含有yield语句 def find_specific_files(root, patterns=[r'.*'], exclude_dirs=[]): # 遍历传入的路径root for root, dirnames, filenames in os.walk(root): # 进行文件名正则匹配 for filename in filenames: # 调用上一个函数进行匹配 if is_file_match(filename, patterns): # 抛出符合条件的拼接路径 yield os.path.join(root, filename) # 进行例外文件夹刨除:每一轮都刨除一遍 for d in exclude_dirs: if d in dirnames: dirnames.remove(d) if __name__ == '__main__': # 正则写后缀名 patterns = [r'.*\.xml$', r'.*\.py$'] exclude_dirs = ['venv'] # 方法一:生成器配合列表生成式 filelist = [item for item in find_specific_files(".", patterns, \ exclude_dirs)] # 方法二:迭代遍历生成器 for i in find_specific_files(".", patterns, exclude_dirs): print(i)
三、路径操作
3.1 路径判断
- 代码示例
import os # 以下均返回布尔值 # 文件判断:不存在也为False os.path.isfile("base") # 文件夹判断:不存在也为False os.path.isdir("base") # 快捷方式判断:ln -s 命令生成的 os.path.islink("base") # 挂载点判断:centos7可以通过df命令查看 os.path.ismount("base") # 指定路径(文件或文件夹)存在与否判断 os.path.exists("./base") # 绝对路径判断:不判断是否存在 os.path.isabs("/root/base")
3.2 路径解析
- 代码示例
# 获取指定相对路径的绝对路径:等同'base' os.path.abspath('./base') >>>'/home/duke/base' # 获取展开用户家目录:不判断是否存在 os.path.expanduser("~/home") >>> '/root/home' # 获取父目录:不管test是文件还是文件夹,不判断是否存在 os.path.dirname("/root/base/test") >>> "/root/base"
3.3 路径拼接
- 代码示例
# 分离文件名和扩展名 os.path.splitext('/root/base.py') >>> ('/root/base', '.py') # 返回父目录与子元素:不判断路径是否存在 os.path.split('/root/base/base.py') >>> ('/root/base', 'base.py') # 连接父目录与子元素:不判断路径是否存在,使用os.sep分隔符 os.path.join("/root/base","base.py") >>> '/root/base/base.py'
四、组合语句
4.1 查找当前目录下的py文件
- 代码示例
import os # 写法一 [item for item in os.listdir() \ if os.path.isfile(item) \ and os.path.splitext(item)[1]=='.py'] # 写法二 [item for item in os.listdir() if item.endswith('.py')] # 写法三:记住这个就行了,复杂匹配用列表生成式和re模块 import glob # 默认获取当前工作目录下的文件,可用os.chdir(r'/mnt/main')修改 # 或在路径中直接写入 # glob.glob(r‘/mnt/main/*.py’),此时返回的列表每个是绝对路径 glob.glob(r'*.py') # 以上三个返回结果均如下 >>>['apis.py', 'config.py']
4.2 获取文件夹下文件大小的字典
- 代码示例
import os {item: os.path.getsize(item) for item in os.listdir() \ if os.path.isfile(item)} # 返回字典:字节数 >>> {'123.py': 17, '345.text': 0, '234.doc': 28}
五、文件操作
5.1 文件时间、大小
- 代码示例
import os # 获取文件 时间戳 # 创建时间:create os.path.getctime("123.py") >>> 1654673213.4272797 # 修改时间:modify os.path.getmtime("123.py") >>> 1654673213.4272797 # 访问时间:access os.path.getatime("123.py") >>> 1654673213.4272797 # 获取 文件大小:字节,文件不存在OSError os.path.getsize('base') >>> 336
5.2 文件比较
- 代码示例
import filecmp # 比较两个文件二进制内容是否相同 filecmp.cmp("123.py", "345.py") >>> True # 比较两个文件夹的一级目录文件 d = filecmp.dircmp("a", "b") d.report() >>> diff a b >>> Only in a : ['123.py'] >>> Only in b : ['345.py'] >>> Identical files : ['234.py'] # 四个变量 d.left_only d.left_list d.right_only d.right_list
5.3 获取文件的md5值
- 代码示例
# 文件名:getfilemd5.py import hashlib import sys # 以生成器方式:每次从文件提取8192个字节返回 def get_chuck(filename): with open(filename) as f: while True: chunk = f.read(8192) if not chunk: break else: yield chunk # 读取完全部文件:提取md5校验码 def get_file_checksum(filename): h = hashlib.md5() for chunk in get_chuck(filename): h.update(chunk.encode("utf8")) return h.hexdigest() if __name__ == '__main__': # 此方法为命令行方式使用 sys.argv.append("") print(get_file_checksum(sys.argv[1])) ######################################### # 使用方法 # ######################################### # 方法一:以命令行方式获取test.py的md5值 # 等价 md5sum test.py python3 getfilemd5.py test.py >>> 4761b856c5dccbad879134690c864d28 # 在程序中直接调用函数 get_file_checksum("test.py") >>> '4761b856c5dccbad879134690c864d28'
5.4 压缩文件
- zip及bz2格式
import shutil # 获取支持的压缩文件格式 shutil.get_archive_formats() >>> [('bztar', "bzip2'ed tar-file"), >>> ('gztar', "gzip'ed tar-file"), >>> ('tar', 'uncompressed tar file'), >>> ('xztar', "xz'ed tar-file"), >>> ('zip', 'ZIP file')] ############################################## # 创建压缩文件 # 压缩文件名(在当前工作目录创建) # 压缩文件格式:bztar、zip常用 # 需要压缩的文件夹 shutil.make_archive("test", 'zip', './a') >>> '/main/a.zip' shutil.make_archive("test", 'bztar', './a') >>> '/main/test.tar.bz2' ############################################## # 查看压缩文件 # 查看bz2压缩文件 import tarfile f = tarfile.open('test.tar.bz2', 'r:bz2') f.getnames() >>> ['.', './123.py', './234.py'] # 查看zip压缩文件 import zipfile z = zipfile.ZipFile("test.zip", "r") for filename in z.namelist(): print(filename) >>> 234.py >>> 123.py ############################################## # 解压缩: # 压缩文件的路径(不写绝对路径则相对当前工作目录) # 解压到的目录(覆盖式创建,只覆盖同名,不写则为'.') # 解压格式:默认按后缀名自动判断 shutil.unpack_archive('test.tar.bz2', './test') shutil.unpack_archive('./main/test.zip', './code/test')
- rar格式(解压缩测试失败)
# 需要pip3 install rarfile import rarfile # 构建rar对象 rf = rarfile.RarFile('test.rar') # 获取rar内文件列表 rf.namelist() >>> ['test/', 'test/123.py', 'test/234.py'] # 解压缩:解压缩的目标文件夹,若无参数,则在当前文件夹创建test文件 # 测试失败: # 官网软件下载:https://www.rarlab.com/rar_add.htm # 官网教程:https://python-unrar.readthedocs.io/en/v0.3/rarfile.html rf.extractall('./a')