操作汇总
常用的操作:
- 获取文件相关信息
- 修改文件相关信息
- 创建文件、目录
- 删除文件、目录
- 复制、移动和重命名
- 遍历文件、目录
- 匹配文件、目录
- 创建和解压ZIP和TAR档案
- 使用
fileinput
模块打开多个文件
相关模块
参考资料: https://juejin.cn/post/6844903774134206472#heading-10
应用场景 | API | 备注 |
---|---|---|
2.x | os.listdir() | 操作费时,经常要配合os.path的其他api才能达到目的 |
3.4 【推荐】 | os.pathlib.Path() | 操作方便,面向对象的api形式 |
3.5 | os.scandir() |
常用的库
- os
- os.path
- shutil
- pathlib
判断文件是否存在
import os
def file_is_exist(filename:str) -> bool:
return os.path.exists(filename)
判断目录是否存在
创建目录
递归创建不存在的目录
import os
pth = r"dir1" # dir1不存在
if not os.path.exists(pth):
os.mkdir(pth)
pth = r"dir2/dir3" # dir2, dir3都不存在
if not os.path.exists(pth):
os.mkidr(pth)
删除文件
- os.remove
- os.unlink
- pathlib.Path.unlink()
import os
data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.remove(data_file)
data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.unlink(data_file)
data_file = 'home/data.txt'
# 如果类型是文件则进行删除
if os.path.is_file(data_file):
os.remove(data_file)
else:
print(f'Error: {data_file} not a valid filename')
os.path.is_file()
检查 data_file
是否实际上是一个文件。 如果是,则通过调用 os.remove()
删除它。 如果 data_file
指向文件夹,则会向控制台输出错误消息。
from pathlib import Path
data_file = Path('home/data.txt')
try:
data_file.unlink()
except IsADirectoryError as e:
print(f'Error: {data_file} : {e.strerror}')
获取文件时间信息
相关模块
# 输出文件访问时间
os.path.getatime(file)
# 输出文件的创建时间
os.path.getctime(file)
# 输出文件最近修改时间
os.path.getmtime(file)
获取文件创建
import os
import time
filename = '.' # 当前路径
filemt = time.localtime(os.stat(filename).st_mtime)
print(time.strftime("%Y-%m-%d", filemt))
# 输出
"""
2019-09-11
"""
最近一次修改
import os
import time
if __name__ == '__main__':
if (len(os.sys.argv) < 1):
raise TypeError()
else:
print("os.sys.argv[0]: %s" % os.sys.argv[0])
# os.sys.argv[0] 是当前文件,在本例中是 test.py , 即为当前运行脚本的绝对地址
f = os.sys.argv[0]
mtime = time.ctime(os.path.getmtime(f))
ctime = time.ctime(os.path.getctime(f))
print("Last modified : %s, last created time: %s" % (mtime, ctime))
# 输出
"""
os.sys.argv[0]: E:/Python/Projects/不是闹着玩儿嘞/example/test/test.py
Last modified : Wed Sep 11 16:39:53 2019, last created time: Thu Feb 28 21:31:05 2019
"""
其他时间信息
import os
import time
time.ctime(os.stat(__file__).st_mtime) # 文件的修改时间
time.ctime(os.stat(__file__).st_ctime) # 文件的创建时间
time.localtime(os.stat(__file__).st_mtime) # 文件访问时间 适合计算时间
# 上面不予赘述 , 用一个做以示例
ModifiedTime = time.localtime(os.stat(__file__).st_mtime) # 文件访问时间
y = time.strftime('%Y', ModifiedTime)
m = time.strftime('%m', ModifiedTime)
d = time.strftime('%d', ModifiedTime)
H = time.strftime('%H', ModifiedTime)
M = time.strftime('%M', ModifiedTime)
print("文件信息打印 ...")
print("Year:%s / Month:%s / Day:%s / Hour:%s / Min:%s" % (y, m, d, H, M))
# 输出
"""
文件信息打印 ...
Year:2019 / Month:09 / Day:11 / Hour:16 / Min:50
"""
获取目标源目录
def get_dir(filename:str) -> str:
from os import path
# 判断文件是否存在
return path.dirname(path.abspath(filename))
遍历、获取目录
区别
os.scandir()
和 pathlib.Path()
返回的都是迭代器,两者最大的区别是pathlib.Path()
采用面向对象设计,语法更加简介和直观
os.listdir()
是非常老旧的内置函数,原生功能非常缺乏,万不得已不要使用
- 2.x
os.listdir() -> list[str]
(不推荐)
def list_dir(tar:str) -> list[str]:
for e in l:
# 列表整个目录各个文件
print(os.path.join(os.path.realPath(l), e))
# 获取整各个文件的后缀,前缀等
eachName,eachExt = os.path.basename(e).split('.')
print(eachName)
目录列表现在看上去不容易阅读,对
os.listdir()
的调用结果需要使用循环打印有助于查看。
- 3.5 -
os.scandir() -> posix.ScandirIterator
返回一个可迭代的对象
def list_dir(tar:str):
import os
with os.scandir(tar) as file_list:
for each_file in file_list:
print(each_file.name)
print('文件类型:', '文件' if each_file.is_file() else "文件夹")
- 3.4
pathlib.Path() -> PosixPath|WindowsPath
(推荐)
pathlib
提供了一组类,以简单并且面向对象的方式提供了路径上的大多数常见的操作。使用 pathlib
比起使用 os
中的函数更加有效。和 os
相比,使用 pathlib
的另一个好处是减少了操作文件系统路径所导入包或模块的数量。
def list_dir(tar:str):
from pathlib import Path
entries = Path('my_directory')
for each_file in entries.iterdir():
print(each_file.name)
pathlib.Path()
返回的是PosixPath
或WindowsPath
对象,这取决于操作系统。
pathlib.Path()
对象有一个.iterdir()
的方法用于创建一个迭代器包含该目录下所有文件和目录。.iterdir()
生成的每个条目都包含文件或目录的信息,例如其名称和文件属性。
pathlib
在Python3.4
时被第一次引入,并且是对Python一个很好的加强,它为文件系统提供了面向对象的接口。
使用 pathlib.Path()
或 os.scandir()
来替代 os.listdir()
是获取目录列表的首选方法,尤其是当你需要获取文件类型和文件属性信息的时候。pathlib.Path()
提供了在 os
和 shutil
中大部分处理文件和路径的功能,并且它的方法比这些模块更加有效。我们将讨论如何快速的获取文件属性。
遍历、匹配指定文件
├── folder_1
│ ├── file1.py
│ ├── file2.py
│ └── file3.py
├── folder_2
│ ├── file4.py
│ ├── file5.py
│ └── file6.py
├── test1.txt
└── test2.txt
os.walk()
import os
def listdir(path:str):
for dir_path, dir_list, file_list in os.walk():
print(f'当前文件夹: {dirpath}')
for file_name in file_list:
print(file_name)
Found directory: .
test1.txt
test2.txt
Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
要以自下而上的方式遍历目录树,则将 topdown=False
关键字参数传递给 os.walk()
:
Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
Found directory: .
test1.txt
test2.txt
如你看见的,程序在列出根目录的内容之前列出子目录的内容。 这在在你想要递归删除文件和目录的情况下非常有用。 你将在以下部分中学习如何执行此操作。 默认情况下,os.walk
不会访问通过软连接创建的目录。 可以通过使用 followlinks = True
参数来覆盖默认行为。
获取目录下所有文件
2.x os.listdir
import os
tar = 'xxx'
for each in os.listdir(tar):
realPath = os.path.join(os.path.realPath(tar), each)
if os.path.isdir(realPath):
print(realPath, '是一个目录')
大于3.5 os.scandir()
import os
l = os.scandir('./xxx/xxx')
# 使用with 上下文管理协议
with os.scandir('xxxx') as d:
for each in d:
if each.is_dir():
print(each.name, '是一个目录')
elif each.is_file(:
print(each.name, '是一个文件')
大于3.4 pathlib库 【建议】
import pathlib
l = pathlib.Path('xxxx')
for each in l.iterdir():
if each.is_dir():
print(each.name, '是一个目录')
elif each.is_file(:
print(each.name, '是一个文件')
from pathlib import Path
def list_dir_file(tar:str):
basepath = Path(tar)
files_in_basepath = (entry for entry in basepath.iterdir() if entry.is_file())
for item in files_in_basepath:
print(item.name)
目录创建
常用的几种创建目录的方法:
方法 | 描述 |
---|---|
os.mkdir() | 创建单个子目录 |
os.makedirs() | 创建多个目录,包括中间目录 |
Pathlib.Path.mkdir() | 创建单个或多个目录 |
如果目录已存在,三个
api
都会抛出FileExistsError
异常
- 基础使用
import os, libpath
# 首先创建一个文件对象
tar = libpath.Path('new_dir_name')
# exist_ok 相当于如果存在,忽略异常
# parents 表示递归创建目录,等价于使用 os.makedirs()
tar.mkdir(exist_ok=True, parents=True)
- 递归创建
获取文件信息
Python可以很轻松的获取文件大小和修改时间等文件属性。可以通过使用 os.stat()
, os.scandir()
或 pathlib.Path
来获取。
os.scandir()
和 pathlib.Path()
能直接获取到包含文件属性的目录列表。这可能比使用 os.listdir()
列出文件然后获取每个文件的文件属性信息更加有效。
获取最后修改时间
def get_file_info(tar):
basepath = Path(tar)
for entry in basepath.iterdir():
info = entry.stat()
print('{} 上次修改时间为 {}'.format(
entry.name,
timestamp2datetime(info.st_mtime)))
import datetime
from pathlib import Path
def timestamp2datetime(timestamp, convert_to_local=True, utc=8, is_remove_ms=True)
"""
转换 UNIX 时间戳为 datetime对象
:param timestamp: 时间戳
:param convert_to_local: 是否转为本地时间
:param utc: 时区信息,中国为utc+8
:param is_remove_ms: 是否去除毫秒
:return: datetime 对象
"""
if is_remove_ms:
timestamp = int(timestamp)
dt = datetime.datetime.utcfromtimestamp(timestamp)
if convert_to_local:
dt = dt + datetime.timedelta(hours=utc)
return dt
def convert_date(timestamp, format='%Y-%m-%d %H:%M:%S'):
dt = timestamp2datetime(timestamp)
return dt.strftime(format)
basepath = Path('my_directory')
for entry in basepath.iterdir():
if entry.is_file()
info = entry.stat()
print('{} 上次修改时间为 {}'.format(
entry.name,
timestamp2datetime(info.st_mtime)))
file3.txt 上次修改时间为 2019-01-24 09:04:39
file2.csv 上次修改时间为 2019-01-24 09:04:39
file1.py 上次修改时间为 2019-01-24 09:04:39
os.scandir()
返回一个 ScandirIterator
对象。ScandirIterator
对象中的每一项有 .stat()
方法能获取关于它指向文件或目录的信息。.stat()
提供了例如文件大小和最后修改时间的信息。在上面的示例中,代码打印了 st_time
属性,该属性是上次修改文件内容的时间。
文件匹配
fnmatch
【勉强能用】
字符串方法匹配的能力是有限的。fnmatch
有对于模式匹配有更先进的函数和方法。
import os,fnmatch
def match_file(dir_path:str, exp:str='data_*_backup.log'):
result_list = []
for each_file in os.listdir(path):
if fnmatch.fnmatch(f_name, exp):
result_list.append(each_file)
glob.glob()
【推荐】
glob
是专门用来匹配的模块
import glob
# 匹配
# recursive 是否递归匹配文件
for name in glob.glob('*[0-9]*.txt', recursive=True):
print(name)
data_01.txt
data_01_backup.txt
data_02.txt
data_02_backup.txt
data_03.txt
data_03_backup.txt
# '*[0-9]*.txt' 匹配上面的文件
# '**/*.py' 匹配所有py文件
def match_file(dir_path:str, exp:str='**/*.py'):
result_list = []
for name in glob.glob('*[0-9]*.txt'):
# 迭代器形式
# for name in glob.iglob('*[0-9]*.txt'):
print(name)
result_list.append(name)
glob.glob()
和 glob.iglob()
不同之处在于,iglob()
返回一个迭代器而不是一个列表。
pathlib
【推荐】
pathlib
也包含类似的方法来灵活的获取文件列表。
from pathlib import Path
def match_file(dir_path:str, exp:str='*.p*'):
p = Path(dir_path)
for name in p.glob(exp):
print(name)
pathlib
混合了许多 os
, os.path
和 glob
模块的最佳特性到一个模块中,这使得使用起来很方便。
os.listdir
【不推荐】
def search_file(path, ext):
result_list = []
for each_file in os.listdir(path):
if each_file.endwith(ext):
pass
因为使用了 os.listdir()
该函数返回的结果均为字符串,所以要对结果进行二次处理必须配合其他字符串方法,扩展性非常差。