Skip to main content

操作汇总

image-20220322165709501

常用的操作:

  • 获取文件相关信息
  • 修改文件相关信息
  • 创建文件、目录
  • 删除文件、目录
  • 复制、移动和重命名
  • 遍历文件、目录
  • 匹配文件、目录
  • 创建和解压ZIP和TAR档案
  • 使用fileinput 模块打开多个文件

相关模块

参考资料: https://juejin.cn/post/6844903774134206472#heading-10

应用场景API备注
2.xos.listdir()操作费时,经常要配合os.path的其他api才能达到目的
3.4 【推荐】os.pathlib.Path()操作方便,面向对象的api形式
3.5os.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() 返回的是 PosixPathWindowsPath 对象,这取决于操作系统。

  • pathlib.Path() 对象有一个 .iterdir() 的方法用于创建一个迭代器包含该目录下所有文件和目录。.iterdir() 生成的每个条目都包含文件或目录的信息,例如其名称和文件属性。

  • pathlibPython3.4时被第一次引入,并且是对Python一个很好的加强,它为文件系统提供了面向对象的接口。

使用 pathlib.Path()os.scandir() 来替代 os.listdir() 是获取目录列表的首选方法,尤其是当你需要获取文件类型和文件属性信息的时候。pathlib.Path() 提供了在 osshutil 中大部分处理文件和路径的功能,并且它的方法比这些模块更加有效。我们将讨论如何快速的获取文件属性。

遍历、匹配指定文件

├── 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 混合了许多 osos.pathglob 模块的最佳特性到一个模块中,这使得使用起来很方便。

os.listdir【不推荐】

def search_file(path, ext):
result_list = []
for each_file in os.listdir(path):
if each_file.endwith(ext):
pass

因为使用了 os.listdir() 该函数返回的结果均为字符串,所以要对结果进行二次处理必须配合其他字符串方法,扩展性非常差。