文章目录
一、python中对文件、文件夹操作时经常用到的os模块和shutil模块常用方法。
-
得到当前工作目录,即当前Python脚本工作的目录路径:
os.getcwd()
-
返回指定目录下的所有文件和目录名:
os.listdir()
-
函数用来删除一个文件:
os.remove()
-
删除多个目录:
os.removedirs(r“c:\python”)
-
检验给出的路径是否是一个文件:
os.path.isfile()
-
检验给出的路径是否是一个目录:
os.path.isdir()
-
判断是否是绝对路径:
os.path.isabs()
-
检验给出的路径是否真地存:
os.path.exists()
-
返回一个路径的目录名和文件名:
os.path.split()
os.path.split('/home/swaroop/byte/code/poem.txt') --->('/home/swaroop/byte/code', 'poem.txt')
-
分离扩展名:
os.path.splitext()
os.path.splitext('poem.txt') --->('poem', '.txt') os.path.splitext('/home/swaroop/byte/code/poem.txt') --->('/home/swaroop/byte/code/poem', '.txt')
-
获取路径名:
os.path.dirname()
-
获取文件名:
os.path.basename()
os.path.basename('/home/swaroop/byte/code/poem.txt') --->'poem.txt'
-
运行shell命令:
os.system()
-
读取和设置环境变量:
os.getenv()
与os.putenv()
-
给出当前平台使用的行终止符:os.linesep Windows使用’\r\n’,Linux使用’\n’而Mac使用’\r’
-
指示你正在使用的平台:os.name 对于Windows,它是’nt’,而对于Linux/Unix用户,它是’posix’
-
重命名:
os.rename(old, new)
-
创建多级目录:
os.makedirs(r“c:\python\test”)
-
创建单个目录:
os.mkdir(“test”)
-
获取文件属性:
os.stat(file)
-
修改文件权限与时间戳:
os.chmod(file)
-
终止当前进程:
os.exit()
-
获取文件大小:
os.path.getsize(filename)
二、文件操作方法大全:
-
os.mknod(“test.txt”) #创建空文件
-
fp = open(“test.txt”,w) #直接打开一个文件,如果文件不存在则创建文件
-
关于open 模式:
w:以写方式打开, a:以追加模式打开 (从 EOF 开始, 必要时创建新文件) r+:以读写模式打开 w+:以读写模式打开 (参见 w ) a+:以读写模式打开 (参见 a ) rb:以二进制读模式打开 wb:以二进制写模式打开 (参见 w ) ab:以二进制追加模式打开 (参见 a ) rb+:以二进制读写模式打开 (参见 r+ ) wb+:以二进制读写模式打开 (参见 w+ ) ab+:以二进制读写模式打开 (参见 a+ )
三、目录操作方法大全
- 创建目录
os.mkdir("file")
- 复制文件:
shutil.copyfile("oldfile","newfile")
#oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile")
#oldfile只能是文件夹,newfile可以是文件,也可以是目标目录 - 复制文件夹:
shutil.copytree("olddir","newdir")
#olddir和newdir都只能是目录,且newdir必须不存在 - 重命名文件(目录)
os.rename("oldname","newname")
#文件或目录都是使用这条命令 - 移动文件(目录)
shutil.move("oldpos","newpos")
- 删除文件
os.remove("file")
- 删除目录
os.rmdir("dir")
#只能删除空目录
shutil.rmtree("dir")
#空目录、有内容的目录都可以删 - 转换目录
os.chdir("path")
#换路径
四、文件综合操作实例
import re
import os
import time
#str.split(string)分割字符串
#'连接符'.join(list) 将列表组成字符串
def change_name(path):
global i
if not os.path.isdir(path) and not os.path.isfile(path):
return False
if os.path.isfile(path):
file_path = os.path.split(path) #分割出目录与文件
lists = file_path[1].split('.') #分割出文件与文件扩展名
file_ext = lists[-1] #取出后缀名(列表切片操作)
img_ext = ['bmp','jpeg','gif','psd','png','jpg']
if file_ext in img_ext:
os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext)
i+=1 #注意这里的i是一个陷阱
#或者
#img_ext = 'bmp|jpeg|gif|psd|png|jpg'
#if file_ext in img_ext:
# print('ok---'+file_ext)
elif os.path.isdir(path):
for x in os.listdir(path):
change_name(os.path.join(path,x)) #os.path.join()在路径处理上很有用
img_dir = 'D:\\xx\\xx\\images'
img_dir = img_dir.replace('\\','/')
start = time.time()
i = 0
change_name(img_dir)
c = time.time() - start
print('程序运行耗时:%0.2f'%(c))
print('总共处理了 %s 张图片'%(i))
os.sep
可以取代操作系统特定的路径分隔符。windows下为 ‘\’os.name
字符串指示你正在使用的平台。比如对于Windows,它是’nt’,而对于Linux/Unix用户,它是 ‘posix’os.getcwd()
函数得到当前工作目录,即当前Python脚本工作的目录路径os.getenv()
获取一个环境变量,如果没有返回none- `os.putenv(key, value) 设置一个环境变量值
- os.listdir(path) 返回指定目录下的所有文件和目录名
- os.remove(path) 函数用来删除一个文件
- os.system(command) 函数用来运行shell命令
- os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用 ‘\r\n’,Linux使用 ‘\n’ 而Mac使用 ‘\r’
- os.path.split(path) 函数返回一个路径的目录名和文件名
- os.path.isfile() 和os.path.isdir()函数分别检验给出的路径是一个文件还是目录
- os.path.exists() 函数用来检验给出的路径是否真地存在
- os.curdir 返回当前目录 (’.’)
- os.mkdir(path) 创建一个目录
- os.makedirs(path) 递归的创建目录
- os.chdir(dirname) 改变工作目录到dirname
- os.path.getsize(name) 获得文件大小,如果name是目录返回0L
- os.path.abspath(name) 获得绝对路径
- os.path.normpath(path) 规范path字符串形式
- os.path.splitext() 分离文件名与扩展名
- os.path.join(path,name) 连接目录与文件名或目录
- os.path.basename(path) 返回文件名
- os.path.dirname(path) 返回文件路径
- os.walk(top,topdown=True,οnerrοr=None) 遍历迭代目录
- os.rename(src, dst) 重命名file或者directory src到dst 如果dst是一个存在的directory, 将抛出OSError. 在Unix, 如果dst在存且是一个file, 如果用户有权限的话,它将被安静的替换. 操作将会失败在某些Unix 中如果src和dst在不同的文件系统中. 如果成功, 这命名操作将会是一个原子操作 (这是POSIX 需要). 在 Windows上, 如果dst已经存在, 将抛出OSError,即使它是一个文件. 在unix,Windows中有效。
- os.renames(old, new) 递归重命名文件夹或者文件。像rename()
shutil 模块
- shutil.copyfile( src, dst) 从源src复制到dst中去。当然前提是目标地址是具备可写权限。抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
- shutil.move( src, dst) 移动文件或重命名
- shutil.copymode( src, dst) 只是会复制其权限其他的东西是不会被复制的
- shutil.copystat( src, dst) 复制权限、最后访问时间、最后修改时间
- shutil.copy( src, dst) 复制一个文件到一个文件或一个目录
- shutil.copy2( src, dst) 在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
- shutil.copy2( src, dst) 如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
- shutil.copytree( olddir, newdir, True/Flase)
把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接 - shutil.rmtree( src ) 递归删除一个目录以及目录内的所有内容
Python文件路径
当前工作目录
每个运行在计算机上的程序, 都有一个“当前工作目录”, 或 cwd。所有没有从根文件夹开始的文件名或路径, 都假定在当前工作目录下。利用 os.getcwd()函数,可以取得当前工作路径的字符串, 并可以利用 os.chdir()改变它。
>>> import os
>>> os.getcwd()
'C:\\Python34'
>>> os.chdir('C:\\Windows\\System32')
>>> os.getcwd()
'C:\\Windows\\System32'
如果要更改的当前工作目录不存在, Python 就会显示一个错误。
>>> os.chdir('C:\\ThisFolderDoesNotExist')
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
os.chdir('C:\\ThisFolderDoesNotExist')
FileNotFoundError: [WinError 2] The system cannot find the file specified:
'C:\\ThisFolderDoesNotExist'
用 os.makedirs()创建新文件夹
程序可以用 os.makedirs()函数
创建新文件夹(目录)。
>>> import os
>>> os.makedirs('C:\\delicious\\walnut\\waffles')
这不仅将创建 C:\delicious 文件夹, 也会在 C:\delicious 下创建 walnut 文件夹,并在 C:\delicious\walnut 中创建 waffles 文件夹。也就是说, os.makedirs()将创建所有必要的中间文件夹,目的是确保完整路径名存在。图 8-3 展示了这个文件夹的层次结构。
处理绝对路径和相对路径
os.path 模块提供了一些函数, 返回一个相对路径的绝对路径, 以及检查给定的路径是否为绝对路径。
- 调用
os.path.abspath(path)
将返回参数的绝对路径的字符串。这是将相对路径转换为绝对路径的简便方法。 - 调用
os.path.isabs(path)
,如果参数是一个绝对路径,就返回 True,如果参数是一个相对路径,就返回 False。 - 调用
os.path.relpath(path, start)
将返回从 start 路径到 path 的相对路径的字符串。如果没有提供 start,就使用当前工作目录作为开始路径。
>>> os.path.abspath('.')
'C:\\Python34'
>>> os.path.abspath('.\\Scripts')
'C:\\Python34\\Scripts'
>>> os.path.isabs('.')
False
>>> os
调用 os.path.dirname(path)
将返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容。调用 os.path.basename(path)
将返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容。
>>> path = 'C:\\Windows\\System32\\calc.exe'
>>> os.path.basename(path)
'calc.exe'
>>> os.path.dirname(path)
'C:\\Windows\\System32'
如果同时需要一个路径的目录名称和基本名称, 就可以调用os.path.split()
,获得这两个字符串的元组,
>>> calcFilePath = 'C:\\Windows\\System32\\calc.exe'
>>> os.path.split(calcFilePath)
('C:\\Windows\\System32', 'calc.exe')
==s.path.split()不会接受一个文件路径并返回每个文件夹的字符串的列表。==如果需要这样,请使用 split()字符串方法,并根据os.path.sep 中的字符串进行分割
。
>>> calcFilePath.split(os.path.sep)
['C:', 'Windows', 'System32', 'calc.exe']
查看文件大小和文件夹内容
一旦有办法处理文件路径, 就可以开始搜集特定文件和文件夹的信息。 os.path 模块提供了一些函数,用于查看文件的字节数以及给定文件夹中的文件和子文件夹。
- 调用
os.path.getsize(path)
将返回 path 参数中文件的字节数。 - 调用
os.listdir(path)
将返回文件名字符串的列表
,包含 path 参数中的每个文件(这个函数在 os 模块中,而不是 os.path)。
>>> os.path.getsize('C:\\Windows\\System32\\calc.exe')
776192
>>> os.listdir('C:\\Windows\\System32')
['0409', '12520437.cpx', '12520850.cpx', '5U877.ax', 'aaclient.dll',
--snip--
'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HK', 'zh-TW', 'zipfldr.dll']
可以看到, 我的计算机上的 calc.exe 程序是 776192 字节。在我的 C:\Windows\system32 下有许多文件。如果想知道这个目录下所有文件的总字节数, 就可以同时使用os.path.getsize()
和 os.listdir()。
>>> totalSize = 0
>>> for filename in os.listdir('C:\\Windows\\System32'):
totalSize = totalSize + os.path.getsize(os.path.join('C:\\Windows\\System32', filename))
>>> print(totalSize)
1117846456
检查路径有效性
如果你提供的路径不存在, 许多 Python 函数就会崩溃并报错。 os.path 模块提供了一些函数,用于检测给定的路径是否存在,以及它是文件还是文件夹。
- 如果 path 参数所指的文件或文件夹存在, 调用
os.path.exists(path)
将返回 True,否则返回 False。 - 如果 path 参数存在,并且是一个文件, 调用
os.path.isfile(path)
将返回 True, 否则返回 False。 - 如果 path 参数存在, 并且是一个文件夹, 调用
os.path.isdir(path)
将返回 True,否则返回 False。
>>> os.path.exists('C:\\Windows')
True
>>> os.path.exists('C:\\some_made_up_folder')
False
>>> os.path.isdir('C:\\Windows\\System32')
True
>>> os.path.isfile('C:\\Windows\\System32')
False
获取目录列表
假设你当前的工作目录有一个叫 my_directory 的子目录,该目录包含如下内容:
├── file1.py
├── file2.csv
├── file3.txt
├── sub_dir
│ ├── bar.py
│ └── foo.py
├── sub_dir_b
│ └── file4.txt
└── sub_dir_c
├── config.py
└── file5.txt
Python内置的 os 模块
有很多有用的方法能被用来列出目录内容和过滤结果。为了获取文件系统中特定目录的所有文件和文件夹列表,可以在遗留版本的Python中使用 os.listdir()
或 在Python 3.x 中使用 os.scandir()
。 如果你还想获取文件和目录属性(如文件大小和修改日期),那么 os.scandir() 则是首选的方法。
使用遗留版本的Python获取目录列表
import os
entries = os.listdir('my_directory')
os.listdir() 返回一个Python列表,其中包含path参数所指目录的文件和子目录的名称。
[‘file1.py’, ‘file2.csv’, ‘file3.txt’, ‘sub_dir’, ‘sub_dir_b’, ‘sub_dir_c’]
目录列表现在看上去不容易阅读,对 os.listdir() 的调用结果使用循环打印有助于查看。
for entry in entries:
print(entry)
使用现代版本的Python获取目录列表
在现代Python版本中,可以使用os.scandir()
和 pathlib.Path
来替代 os.listdir()
。
os.scandir()
调用时返回一个迭代器而不是一个列表。
import os
entries = os.scandir('my_directory')
print(entries)
# <posix.ScandirIterator at 0x105b4d4b0>
ScandirIterator 指向了当前目录中的所有条目。你可以遍历迭代器的内容,并打印文件名。
import os
with os.scandir('my_directory') as entries:
for entry in entries:
print(entry.name)
另一个获取目录列表的方法是使用pathlib 模块
:
from pathlib import Path
entries = Path('my_directory')
for entry in entries.iterdir():
print(entry.name)
pathlib.Path() 返回的是 PosixPath 或 WindowsPath 对象,这取决于操作系统。
pathlib.Path() 对象有一个 .iterdir() 的方法用于创建一个迭代器包含该目录下所有文件和目录。由 .iterdir() 生成的每个条目都包含文件或目录的信息,例如其名称和文件属性。
在上面的例子中,你调用 pathlib.Path() 并传入了一个路径参数。然后调用 .iterdir() 来获取 my_directory 下的所有文件和目录列表。
| os.listdir() | 以列表的方式返回目录中所有的文件和文件夹 | | os.scandir() | 返回一个迭代器包含目录中所有的对象,对象包含文件属性信息 | | pathlib.Path().iterdir() | 返回一个迭代器包含目录中所有的对象,对象包含文件属性信息 |
列出目录中的所有文件
如何使用 os.listdir()
,os.scandir()
和 pathlib.Path()
打印出目录中文件的名称。为了过滤目录并仅列出 os.listdir()
生成的目录列表的文件,要使用 os.path
:
import os
basepath = 'my_directory'
for entry in os.listdir(basepath):
# 使用os.path.isfile判断该路径是否是文件类型
if os.path.isfile(os.path.join(base_path, entry)):
print(entry)
在这里调用 os.listdir()
返回指定路径中所有内容的列表,接着使用os.path.isfile()
过滤列表让其只显示文件类型而非目录类型。
输出:
file1.py
file2.csv
file3.txt
一个更简单的方式来列出一个目录中所有的文件是使用 os.scandir()
或 pathlib.Path()
:
import os
basepath = 'my_directory'
with os.scandir(basepath) as entries:
for entry in entries:
if entry.is_file():
print(entry.name)
如何使用 pathlib.Path() 列出一个目录中的文件:
basepath = Path('my_directory')
for entry in basepath.iterdir():
if entry.is_file():
print(entry.name)
列出子目录
如果要列出子目录而不是文件,请使用下面的方法。现在展示如何使用 os.listdir()
和 os.path()
:
basepath = 'my_directory'
for entry in os.listdir(basepath):
if os.path.isdir(os.path.join(basepath, entry)):
print(entry)
使用 os.scandir() :
import os
basepath = 'my_directory'
with os.scandir(basepath) as entries:
for entry in entries:
if entry.is_dir():
print(entry.name)
使用 pathlib.Path()
:
basepath = Path('my_directory')
for entry in basepath.iterdir():
if entry.is_dir():
print(entry.name)
输出:
sub_dir_c
sub_dir_b
sub_dir
获取文件属性
Python可以很轻松的获取文件大小和修改时间等文件属性。可以通过使用 os.stat()
, os.scandir()
或 pathlib.Path
来获取。
os.scandir()
和 pathlib.Path()
能直接获取到包含文件属性的目录列表。这可能比使用 os.listdir()
列出文件然后获取每个文件的文件属性信息更加有效。
下面的例子显示了如何获取 my_directory 中文件的最后修改时间()。以时间戳的方式输出:
import os
with os.scandir('my_directory') as entries:
for entry in entries:
info = entry.stat()
print(info.st_mtime)
pathlib 模块具有相应的方法,用于获取相同结果的文件信息:
from pathlib import Path
basepath = Path('my_directory')
for entry in basepath.iterdir():
info = entry.stat()
print(info.st_mtime)
创建目录
你编写的程序迟早需要创建目录以便在其中存储数据。 os 和 pathlib 包含了创建目录的函数。
os.mkdir()
| 创建单个子目录 | |
os.makedirs()
| 创建多个目录,包括中间目录 | | Pathlib.Path.mkdir()
| 创建单个或多个目录 |
import os
os.mkdir('example_directory')
如果该目录已经存在,os.mkdir()
将抛出 FileExistsError 异常。或者,你也可以使用 pathlib
来创建目录:
from pathlib import Path
p = Path('example_directory')
p.mkdir()
如果路径已经存在,mkdir()
会抛出 FileExistsError 异常:
FileExistsError: [Errno 17] File exists: 'example_directory'
为了避免像这样的错误抛出, 当发生错误时捕获错误并让你的用户知道:
from pathlib import Path
p = Path('example_directory')
try:
p.mkdir()
except FileExistsError as e:
print(e)
创建多个目录
os.makedirs()
和os.mkdir()
类似。两者之间的区别在于,os.makedirs()
不仅可以创建单独的目录,还可以递归的创建目录树。换句话说,它可以创建任何必要的中间文件夹,来确保存在完整的路径。
import os
os.makedirs('2018/10/05', mode=0o770)
文件名模式匹配
使用上述方法之一获取目录中的文件列表后,你可能希望搜索和特定的模式匹配的文件。
endswith() 和 startswith()
字符串方法
fnmatch.fnmatch()
glob.glob()
pathlib.Path.glob()
使用字符串方法
Python有几个内置 修改和操作字符串 的方法。当在匹配文件名时,其中的两个方法 .startswith()
和 .endswith()
非常有用。要做到这点,首先要获取一个目录列表,然后遍历。
import os
for f_name in os.listdir('some_directory'):
if f_name.endswith('.txt'):
print(f_name)
使用 fnmatch
进行简单文件名模式匹配
字符串方法匹配的能力是有限的。fnmatch
有对于模式匹配有更先进的函数和方法。我们将考虑使用 fnmatch.fnmatch()
,这是一个支持使用*
和 ?
等通配符的函数。例如,使用 fnmatch 查找目录中所有 .txt 文件,你可以这样做:
import os
import fnmatch
for f_name in os.listdir('some_directory'):
if fnmatch.fnmatch(f_name, '*.txt'):
print(f_name)
更先进的模式匹配
假设你想要查找符合特定掉件的 .txt 文件。例如,你可能指向找到包含单次 data 的 .txt文件,一组下划线之间的数字,以及文件名中包含单词 backup 。就类似于 data_01_backup, data_02_backup, 或 data_03_backup 。
import os
import fnmatch
for f_name in os.listdir('some_directory'):
if fnmatch.fnmatch(f_name, 'data_*_backup.txt'):
print(f_name)
这里就仅仅打印出匹配 data_*_backup.txt 模式的文件名称。模式中的 * 将匹配任何字符,因此运行这段代码则将查找文件名以 data 开头并以 backup.txt 的所有文本文件,就行下面的输出所示 :
data_01_backup.txt
data_02_backup.txt
data_03_backup.txt
遍历目录和处理文件
一个常见的编程任务是遍历目录树并处理目录树中的文件。让我们来探讨一下如何使用内置的Python函数 os.walk()
来实现这一功能。os.walk()
用于通过从上到下或从下到上遍历树来生成目录树中的文件名。处于本节的目的,我们想操作以下的目录树:
import os
for dirpath, dirname, files in os.walk('.'):
print(f'Found directory: {dirpath}')
for file_name in files:
print(file_name)
os.walk() 在每个循环中返回三个值:
当前文件夹的名称
当前文件夹中子文件夹的列表
当前文件夹中文件的列表
在每次迭代中,会打印出它找到的子目录和文件的名称:
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