目录
1 os与os.path的关系
os和os.path是两个模块,不能将path看作os的子模块。对于二者的联系,可以从os的一段源码中加以观察,摘录如下:
if 'posix' in _names:
name = 'posix'
linesep = '\n'
from posix import *
try:
from posix import _exit
__all__.append('_exit')
except ImportError:
pass
import posixpath as path
try:
from posix import _have_functions
except ImportError:
pass
import posix
__all__.extend(_get_exports_list(posix))
del posix
elif 'nt' in _names:
name = 'nt'
linesep = '\r\n'
from nt import *
try:
from nt import _exit
__all__.append('_exit')
except ImportError:
pass
import ntpath as path
import nt
__all__.extend(_get_exports_list(nt))
del nt
try:
from nt import _have_functions
except ImportError:
pass
else:
raise ImportError('no os specific module found')
sys.modules['os.path'] = path
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
devnull)
首先是一段长长的if判断语句,这段语句的目的是导入posixpath模块或者ntpath模块,导入哪一个取决于操作系统,对于windows系统来说导入的是ntpath,导入后以path的名称使用(import ntpath as path)。
sys.modules['os.path'] = path 揭示了os和os.path的关系,sys.modules是一个记录了当前程序导入的所有模块的字典,字典的值是上面导入的别名为path的模块(一个对象),os.path作为一个名称通过键值对的方式指向这个对象的内存地址。因此,导入os模块的同时也就导入了os.path模块。
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, devnull) 表明os中还导入了curdir、pardir、sep等一系列的属性,因此我们通过 os.属性名 调用这些属性时,实际上是通过os调用os.path模块中的属性。
os模块和os.path模块的分工是:os用于支持文件/目录的增、删、改、查等处理,os.path用于支持文件属性信息的相关操作。
2 os和os.path的常用属性和方法
2.1 os模块常用属性
本节以表格的形式列举经常用到的属性。调用这些属性能够很好地支持跨平台操作,比如在不同操作系统路径分割符不同,就能够通过os.sep获取,避免了直接输入造成的不兼容现象。
常用属性 | 返回内容 | windows下返回值 |
os.name | 当前操作系统 | nt |
os.curdir | 当前目录标识符 | . |
os.pardir | 上一层目录标识符 | .. |
os.sep | 路径名分隔符 | \\ |
os.extsep | 文件名与扩展名分隔符 | . |
os.linesep | 文本文件行分隔符 | \r\n |
2.2 os模块常用方法
这里列举os模块提供的关于文件/目录的查询、新建、修改、删除等常用操作的方法。
常用方法 | 参数 | 功能 | 返回值类型 |
os.getcwd() | 无 | 获取当前工作目录 | str |
os.chdir(path) | 目录路径 | 修改当前工作目录到指定路径 | 无 |
os.listdir(path) | 目录路径,不传参为当前目录 | 获取指定目录下的所有文件与目录 | list |
os.mkdir(path) | 目录路径 | 新建目录 | 无 |
os.makedirs(path) | 目录路径 | 新建多层目录 | 无 |
os.rename(path1,path2) | 原路径,新路径 | 重命名与移动文件或目录 | 无 |
os.rmdir(path) | 目录地址 | 删除空目录 | 无 |
os.removedirs(path) | 目录路径 | 删除多层空目录 | 无 |
os.remove(path) | 文件路径 | 删除指定文件 | 无 |
需要注意的是:如果要删除一个非空的目录,首先用os.remove()方法删除这个目录下所有文件,再用os.rmdir()方法删除已经清空的目录
2.3 os.path模块常用方法
os.path主要用于文件属性信息的相关操作,这里分两部分列举该模块下的常用方法,一是路径的常用操作,二是文件/目录访问时间与大小查询。
2.3.1 路径的分割与拼接
路径是以字符串的形式表达的,os.path中关于路径的方法中很多都是路径字符串的分割或拼接。列举如下:
1 os.path.abspath(str):获取文件/目录的绝对路径
参数是一个字符串,可以是存在文件或目录,也可以是不存在的文件和目录,返回值是传入的字符串与当前目录组成的绝对路径,例如:
import os
# 先打印出当前路径
cwd = os.getcwd()
print(cwd) # E:\开发项目\os-note
abs_path = os.path.abspath("a.txt")
print(abs_path)
# 返回绝对路径:E:\开发项目\os-note\a.txt
abs_path = os.path.abspath(r"..\folder")
print(abs_path)
# 返回与上一层目录组成的绝对路径:E:\开发项目\folder
2 os.path.basename(path):返回路径中最后一级目录或文件
import os
# 获取路径最后一级的目录名
base_dir = os.path.basename(r"E:\开发项目\os-note\last_dir")
print(base_dir) # last_dir
# 获取路径中的完整文件名
base_file = os.path.basename(r"E:\开发项目\os-note\a.txt")
print(base_file) # a.txt
3 os.path.dirname(path):返回路径最后一级目录或文件的上层目录的完整路径
import os
# 获取最后一级目录之前的路径
dir_name = os.path.dirname(r"E:\开发项目\os-note\last_dir")
print(dir_name) # E:\开发项目\os-note
# 获取文件名之前的路径
dir_name = os.path.dirname(r"E:\开发项目\os-note\a.txt")
print(dir_name) # E:\开发项目\os-note
4 os.path.split(path):将dirname和basename分隔开来,返回一个元组
import os
# 分隔 最后一级目录 与 上层目录的路径
split_tuple = os.path.split(r"E:\开发项目\os-note\last_dir")
print(split_tuple) # ('E:\\开发项目\\os-note', 'last_dir')
# 分隔 文件 与 上层目录的路径
split_tuple = os.path.split(r"E:\开发项目\os-note\a.txt")
print(split_tuple) # ('E:\\开发项目\\os-note', 'a.txt')
5 os.path.splitext(path):将文件或路径中的扩展名与其前面的部分分隔开,返回一个元组
import os
# 分隔 文件名/路径 与 扩展名
splitext_tuple = os.path.splitext("a.txt")
print(splitext_tuple) # ('a', '.txt')
splitext_tuple = os.path.splitext(r"E:\开发项目\os-note\a.txt")
print(splitext_tuple) # ('E:\\开发项目\\os-note\\a', '.txt')
6 os.path.splitdrive(path):将路径中的驱动器与其后面的部分分隔开,返回一个元组
import os
# 分隔 驱动器 与 路径
splitdrive_tuple = os.path.splitdrive(r"E:\开发项目\os-note\a.txt")
print(splitdrive_tuple) # ('E:', '\\开发项目\\os-note\\a.txt')
7 os.path.join(*str):路径的拼接,支持两个及以上的路径部分
import os
# 路径的拼接
path_join = os.path.join("D:\\python-note\\os-note", "a.xlsx")
print(path_join) # D:\python-note\os-note\a.xlsx
path_join = os.path.join("D:\\python-note", "os-note", "note", "a.txt")
print(path_join) # D:\python-note\os-note\note\a.txt
8 os.path.isabs(path):判断是否是绝对路径,返回布尔值
import os
b = os.path.isabs(r"D:\\python-note\\os-note\\4.xlsx")
print(b) # True
b = os.path.isabs(r"..\\4.xlsx")
print(b) # False
9 os.path.isdir(path):判断路径是否指向一个存在的目录,返回布尔值
import os
b = os.path.isdir(r"D:\\python-note\\os-note")
print(b) # True 指向一个 存在 的目录
b = os.path.isdir(r"D:\\python-note\\abc")
print(b) # False 指向一个 不存在 的目录
b = os.path.isdir(r"..\\4.xlsx")
print(b) # False 指向的不是目录
10 os.path.isdir(path):判断路径是否指向一个存在的文件,返回布尔值
import os
b = os.path.isfile(r"D:\\python-note\\os-note")
print(b) # False 指向的不是文件
b = os.path.isfile(r"D:\\python-note\\6.xlsx")
print(b) # False 指向的是一个 不存在 的文件
b = os.path.isfile(r"D:\\python-note\\os-note\\4.xlsx")
print(b) # True 指向的是一个 存在 的文件
2.3.2 文件/目录的信息查询(时间、大小等)
1 os.path.getatime(path):文件或目录的最近访问时间,返回时间戳(浮点数)
import os
import time
# 文件的最近访问时间
at = os.path.getatime(r"D:\\python-note\\os-note\\4.xlsx")
print(at) # 浮点数时间戳:1621404235.672548
print(time.ctime(at)) # 格式化:Wed May 19 14:03:55 2021
# 目录的最近访问时间
at = os.path.getatime(r"D:\\python-note\\os-note")
print(time.ctime(at)) # Mon May 24 19:56:51 2021
2 os.path.getctime(path):文件或目录的最近创建时间,返回时间戳(浮点数)
import os
import time
# 文件的最近创建时间
ct = os.path.getctime(r"D:\\python-note\\os-note\\4.xlsx")
print(time.ctime(ct)) # Wed May 19 10:59:07 2021
# 目录的最近创建时间
ct = os.path.getctime(r"D:\\python-note\\os-note")
print(time.ctime(ct)) # Wed May 19 10:54:51 2021
3 os.path.getmtime(path):文件或目录的最近修改时间,返回时间戳(浮点数)
import os
import time
# 文件的最近创建时间
mt = os.path.getmtime(r"D:\\python-note\\os-note\\4.xlsx")
print(time.ctime(mt)) # Thu Apr 8 11:34:40 2021
# 目录的最近创建时间
mt = os.path.getctime(r"D:\\python-note\\os-note")
print(time.ctime(mt)) # Wed May 19 10:54:51 2021
4 os.path.getsize(path):文件的大小,返回整数,单位是bit
import os
# 获取文件的大小
size = os.path.getsize(r"D:\\python-note\\os-note\\4.xlsx")
print(size) # 22197
# 将单位转换成kB,保留两位小数
size = size / 1024
print("文件大小为:%.2f kB" % size) # 文件大小为:21.68 kB
5 os.path.exists(path):文件或目录是否存在
该方法返回布尔值,在创建文件或目录之前,常常习惯于先判断要创建的目录或文件是否存在
import os
path = r"D:\\python-note\\os-note\\new_folder"
# 判断要创建的目录是否存在
is_exist = os.path.exists(path)
# 如果不存在,创建该目录
if not is_exist:
os.mkdir(path)
3 文件遍历的两种方法
3.1 采用os.listdir()获取文件列表并遍历
案例:遍历指定目录及其所有子目录,找到所有文件,并打印出绝对路径
import os
def get_all_files(path):
try:
files = os.listdir(path) # 获取文件列表
if files: # 如果文件列表不为空
for file in files: # 遍历文件列表
path_join = os.path.join(path, file) # 拼接绝对路径
if (os.path.isfile(path_join)): # 如果是文件
print(path_join)
else: # 如果不是文件,就是目录,递归调用方法
get_all_files(path_join)
else:
pass
except FileNotFoundError:
pass
get_all_files(r"D:\\python-note")
运行结果
D:\\python-note\hello.txt
D:\\python-note\os-note\4.xlsx
D:\\python-note\os-note\newFolder\2.csv
D:\\python-note\os-note\newFolder2\3.xlsx
D:\\python-note\os-note\test-rename.csv
3.2 采用os.walk()方法遍历
第一个参数是路径,第二个参数是遍历模式,topdown默认为True:优先遍历外层目录,topdown设置为False:优先遍历内层目录。
返回的是一个生成器(generator)对象,用for循环遍历,每一次遍历得到一个元组,内容包括:根目录、目录列表、文件列表
topdown=True的示例:
import os
# 优先遍历外层目录,从外向内遍历
for root, dirs, files in os.walk(r"D:\\python-note"):
print(root, dirs, files)
运行结果
D:\\python-note ['newFolder2', 'os-note'] ['hello.txt'] 优先得到最外层的根、目录列表、文件列表
D:\\python-note\newFolder2 [] []
D:\\python-note\os-note ['newFolder', 'newFolder2'] ['4.xlsx', 'test-rename.csv']
D:\\python-note\os-note\newFolder [] ['2.csv']
D:\\python-note\os-note\newFolder2 [] ['3.xlsx']
topdown=False的示例:
import os
for root, dirs, files in os.walk(r"D:\\python-note", False):
print(root, dirs, files)
运行结果
D:\\python-note\newFolder2 [] []
D:\\python-note\os-note\newFolder [] ['2.csv']
D:\\python-note\os-note\newFolder2 [] ['3.xlsx']
D:\\python-note\os-note ['newFolder', 'newFolder2'] ['4.xlsx', 'test-rename.csv']
D:\\python-note ['newFolder2', 'os-note'] ['hello.txt'] 最后得到最外层的根、目录列表、文件列表
用os.path.walk()方法完成上一节的案例,只需要三行代码
import os
for root, dirs, files in os.walk(r"D:\\python-note"):
for file in files:
print(os.path.join(root,file))
运行结果
D:\\python-note\hello.txt
D:\\python-note\os-note\4.xlsx
D:\\python-note\os-note\test-rename.csv
D:\\python-note\os-note\newFolder\2.csv
D:\\python-note\os-note\newFolder2\3.xlsx