本文将详细解释这些函数的使用方法。首先,我们介绍Python语言中类似于Windows系统的dir命令的列出文件功能,然后描述如何测试一个文件名对应的是一个标准文件、目录还是链接,以及提取文件大小和日期的方法。之后,我们还将介绍如何删除文件和目录,如何复制和删除文件,以及怎样将一个完整的文件路径分解成目录部分和文件名部分,最后,我们讲解目录的创建,以及如何在目录树中移动目录并处理文件。
一、显示目录内容
当我们想要列出当前目录中所有扩展名为.jpg或.gif的文件的时候,就可以使用glob模块来完成此项任务,如下所示:
import glob
filelist = glob.glob('*.jpg') + glob.glob('*.gif')
上述代码使用了glob函数,该函数的参数为要显示的文件类型。在这里,文件类型是通过类似UNIX操作系统shell风格通配符描述的一些文件名来指定的。这些通配符的使用方法,具体请参考fnmatch模块的文档,那里有具体的说明和示例。
为了显示一个目录中的全部文件,可以使用如下所示的os.listdir函数:
files = os.listdir(r'C:\hpl\scripting\src\py\intro') #适用于 Windows
files = os.listdir('/home/hpl/scripting/src/py/intro') # 适用于Unix
# 跨平台版本:
files = os.listdir(os.path.join(os.environ['scripting'],
'src', 'py', 'intro'))
files = os.listdir(os.curdir) # 当前目录中的所有文件
files = glob.glob('*') + glob.glob('.*')
二、测试文件类型
我们知道,文件名、目录名和链接名都是用一个字符串作为其标识符的,但是给我们一个标识符,我们该如何确定它所指的到底是常规文件文件名、目录名还是链接名呢?这时,我们可以使用os.path模块提供的isfile函数、isdir函数和islink函数来达成我们的目标,如下所示:
print myfile, '是一个',
if os.path.isfile(myfile):
print 'plain file'
if os.path.isdir(myfile):
print 'directory'
if os.path.islink(myfile):
print 'link'
您还可以查找文件的日期及其大小:
time_of_last_access = os.path.getatime(myfile)
time_of_last_modification = os.path.getmtime(myfile)
size = os.path.getsize(myfile)
这里的时间以秒为单位,并且从1970年1月1日开始算起。为了获取以天为单位的最后访问日期,可以使用下列代码:
import time # time.time()返回当前时间
age_in_days = (time.time()-time_of_last_access)/(60*60*24)
为了获取文件的详细信息,可以使用os.stat函数和stat模块中的其它实用程序来达到目的,如下:
import stat
myfile_stat = os.stat(myfile)
size = myfile_stat[stat.ST_SIZE]
mode = myfile_stat[stat.ST_MODE]
if stat.S_ISREG(mode):
print '%(myfile)是一个常规文件,大小为 %(size)d 字节' %\
vars()
有关stat模块的详细信息,请参见Python Library Reference。若想测试一个文件的读、写以及执行权限,可以用os.access函数,具体如下所示:
if os.access(myfile, os.W_OK):
print myfile, '具有写权限'
if os.access(myfile, os.R_OK | os.W_OK | os.X_OK):
print myfile, '具有读、写以及执行权限'
像上面这样的测试代码,对CGI脚本来说非常有用。
三、文件和目录的删除
若要删除单个文件的话,可以使用os.remove函数,例如:os.remove('mydata.dat')。Os.remove的别名是os.unlink,不过后者跟传统的UNIX操作系统以及Perl中清除文件的函数重名。我们可以使用下列方式来删除一组文件,如所有以.jpg以及*.gif为扩展名的文件:
for file in glob.glob('*.jpg') + glob.glob('*.gif'):
os.remove(file)
大家知道,只有当目录中内容已经被清空的时候,我们才可以使用rmdir命令来删除该目录。不过,我们经常想要删除一个含有许多文件的目录树,这时我们可以使用shutil模块提供的rmtree函数,如下所示:
shutil.rmtree('mydir')
它相当于UNIX操作系统中的命令rm -rf mydir。
我们可以建立一个自定义函数,使其在进行删除操作的时候将文件和目录做同等对待,其典型用法如下所示:
remove('my.dat') #删除当个文件my.dat
remove('mytree') #删除单个目录树 mytree
# 通过字符串列表中的名称来删除多个文件/目录树:
remove(glob.glob('*.tmp') + glob.glob('*.temp'))
remove(['my.dat','mydir','yourdir'] + glob.glob('*.data'))
下面是remove函数的实现:
def remove(files):
"""删除一个或多个文件和/或目录。"""
if isinstance(files, str): # files是个字符串吗?
files = [files] # 把files从字符串转为列表
if not isinstance(files, list): # files不是列表吗?
for file in files:
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file):
os.remove(file)
下面测试一下remove函数的灵活性:
# 建立10个目录tmp_* ,以及10各文件tmp__*:
for i in range(10):
os.mkdir('tmp_'+str(i))
f = open('tmp__'+str(i), 'w'); f.close()
remove('tmp_1') # tmp_1为目录
remove(glob.glob('tmp_[0-9]') + glob.glob('tmp__[0-9]'))
作为上述remove函数实现的一个注记,我们进行了下列测试:
if not isinstance(files, list):
它实际上是过于严厉。我们需要的只是一个被遍历的一个文件/目录名序列。实际上,我们并不关心名称是否存储在一个列表、元组或者数值数组中,所以更好的测试应该像下面这样:
if not operator.isSequenceType(files):
四、文件的复制与重命名
当我们要复制文件的时候,可以使用shutil模块:
一、显示目录内容
当我们想要列出当前目录中所有扩展名为.jpg或.gif的文件的时候,就可以使用glob模块来完成此项任务,如下所示:
import glob
filelist = glob.glob('*.jpg') + glob.glob('*.gif')
上述代码使用了glob函数,该函数的参数为要显示的文件类型。在这里,文件类型是通过类似UNIX操作系统shell风格通配符描述的一些文件名来指定的。这些通配符的使用方法,具体请参考fnmatch模块的文档,那里有具体的说明和示例。
为了显示一个目录中的全部文件,可以使用如下所示的os.listdir函数:
files = os.listdir(r'C:\hpl\scripting\src\py\intro') #适用于 Windows
files = os.listdir('/home/hpl/scripting/src/py/intro') # 适用于Unix
# 跨平台版本:
files = os.listdir(os.path.join(os.environ['scripting'],
'src', 'py', 'intro'))
files = os.listdir(os.curdir) # 当前目录中的所有文件
files = glob.glob('*') + glob.glob('.*')
二、测试文件类型
我们知道,文件名、目录名和链接名都是用一个字符串作为其标识符的,但是给我们一个标识符,我们该如何确定它所指的到底是常规文件文件名、目录名还是链接名呢?这时,我们可以使用os.path模块提供的isfile函数、isdir函数和islink函数来达成我们的目标,如下所示:
print myfile, '是一个',
if os.path.isfile(myfile):
print 'plain file'
if os.path.isdir(myfile):
print 'directory'
if os.path.islink(myfile):
print 'link'
您还可以查找文件的日期及其大小:
time_of_last_access = os.path.getatime(myfile)
time_of_last_modification = os.path.getmtime(myfile)
size = os.path.getsize(myfile)
这里的时间以秒为单位,并且从1970年1月1日开始算起。为了获取以天为单位的最后访问日期,可以使用下列代码:
import time # time.time()返回当前时间
age_in_days = (time.time()-time_of_last_access)/(60*60*24)
为了获取文件的详细信息,可以使用os.stat函数和stat模块中的其它实用程序来达到目的,如下:
import stat
myfile_stat = os.stat(myfile)
size = myfile_stat[stat.ST_SIZE]
mode = myfile_stat[stat.ST_MODE]
if stat.S_ISREG(mode):
print '%(myfile)是一个常规文件,大小为 %(size)d 字节' %\
vars()
有关stat模块的详细信息,请参见Python Library Reference。若想测试一个文件的读、写以及执行权限,可以用os.access函数,具体如下所示:
if os.access(myfile, os.W_OK):
print myfile, '具有写权限'
if os.access(myfile, os.R_OK | os.W_OK | os.X_OK):
print myfile, '具有读、写以及执行权限'
像上面这样的测试代码,对CGI脚本来说非常有用。
三、文件和目录的删除
若要删除单个文件的话,可以使用os.remove函数,例如:os.remove('mydata.dat')。Os.remove的别名是os.unlink,不过后者跟传统的UNIX操作系统以及Perl中清除文件的函数重名。我们可以使用下列方式来删除一组文件,如所有以.jpg以及*.gif为扩展名的文件:
for file in glob.glob('*.jpg') + glob.glob('*.gif'):
os.remove(file)
大家知道,只有当目录中内容已经被清空的时候,我们才可以使用rmdir命令来删除该目录。不过,我们经常想要删除一个含有许多文件的目录树,这时我们可以使用shutil模块提供的rmtree函数,如下所示:
shutil.rmtree('mydir')
它相当于UNIX操作系统中的命令rm -rf mydir。
我们可以建立一个自定义函数,使其在进行删除操作的时候将文件和目录做同等对待,其典型用法如下所示:
remove('my.dat') #删除当个文件my.dat
remove('mytree') #删除单个目录树 mytree
# 通过字符串列表中的名称来删除多个文件/目录树:
remove(glob.glob('*.tmp') + glob.glob('*.temp'))
remove(['my.dat','mydir','yourdir'] + glob.glob('*.data'))
下面是remove函数的实现:
def remove(files):
"""删除一个或多个文件和/或目录。"""
if isinstance(files, str): # files是个字符串吗?
files = [files] # 把files从字符串转为列表
if not isinstance(files, list): # files不是列表吗?
for file in files:
if os.path.isdir(file):
shutil.rmtree(file)
elif os.path.isfile(file):
os.remove(file)
下面测试一下remove函数的灵活性:
# 建立10个目录tmp_* ,以及10各文件tmp__*:
for i in range(10):
os.mkdir('tmp_'+str(i))
f = open('tmp__'+str(i), 'w'); f.close()
remove('tmp_1') # tmp_1为目录
remove(glob.glob('tmp_[0-9]') + glob.glob('tmp__[0-9]'))
作为上述remove函数实现的一个注记,我们进行了下列测试:
if not isinstance(files, list):
它实际上是过于严厉。我们需要的只是一个被遍历的一个文件/目录名序列。实际上,我们并不关心名称是否存储在一个列表、元组或者数值数组中,所以更好的测试应该像下面这样:
if not operator.isSequenceType(files):
四、文件的复制与重命名
当我们要复制文件的时候,可以使用shutil模块: