3.14. The os module

os 模块有许多可用于操纵文件和进程的有用函数,并且 os.path 有可用于操纵文件和目录路径的函数。

例 3.34. 构造路径名

>>> import os
>>> os.path.join("c:\\music\\ap\\", "mahadeva.mp3") 1 2
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.join("c:\\music\\ap", "mahadeva.mp3")   3
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.expanduser("~")                         4
'c:\\Documents and Settings\\mpilgrim\\My Documents'
>>> os.path.join(os.path.expanduser("~"), "Python") 5
'c:\\Documents and Settings\\mpilgrim\\My Documents\\Python'
1 os.path 是一个模块的引用;使用哪一个模块要看你正运行在哪种平台上。就象 getpass 通过将 getpass 设置为一个与平台相关的函数从而封装了平台之间的不同。
2 os.pathjoin 函数用一个或多个部分路径名构造成一个路径名。在这个简单的例子中,它只是将字符串进行连接。(请注意在Windows下处理路径名是一个麻烦的事,因为反斜线字符必须被转义。)
3

在这个几乎没有价值的例子中,在将路径名加到文件名上之前,join 将在路径名后添加额外的反斜线。当我发现这一点时我高兴极了,因为当用一种新的语言创建我自已的工具包时,addSlashIfNecessary 总是我必须要写的那些愚蠢的小函数之一。在Python中不要写这样的愚蠢的小函数,聪明的人已经为你考虑到了。

4 expanduser 将对使用~来表示当前用户根目录的路径名进行扩展。在任何平台上,只要用户拥有一个根目录,它就会有效,象Windows,UNIX,和Mac OS X;在Mac OS上无效。
5 将这些技术合在一起,你可以容易地对在用户根目录下为目录和文件构造出路径名。

例 3.35. 分割路径名

>>> os.path.split("c:\\music\\ap\\mahadeva.mp3")                        1
('c:\\music\\ap', 'mahadeva.mp3')
>>> (filepath, filename) = os.path.split("c:\\music\\ap\\mahadeva.mp3") 2
>>> filepath                                                            3
'c:\\music\\ap'
>>> filename                                                            4
'mahadeva.mp3'
>>> (shortname, extension) = os.path.splitext(filename)                 5
>>> shortname
'mahadeva'
>>> extension
'.mp3'
1 split 函数对一个全路径名进行分割,返回一个包含路径和文件名的元组。还记得我说过你可以使用多变量赋值从一个函数返回多个值吗?对,split 就是这样一个函数。
2 我们将 split 函数的返回值赋值给一个两个变量的元组。每个变量接收到返回的元组相对应的元素值。
3 第一个变量,filepath,接收到从 split 返回的元组的第一个元素的值,文件路径。
4 第二个变量,filename,接收到从 split 返回的元组的第二个元素的值,文件名。
5 os.path 也包含了一个 splitext 函数,可以用来对文件名进行分割,并且回一个包含了文件名和文件扩展名的元组。我们使用相同的技术来将它们赋值给独立的变量。

例 3.36. 列出目录

>>> os.listdir("c:\\music\\_singles\\")                                          1
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3', 'kairo.mp3',
'long_way_home1.mp3', 'sidewinder.mp3', 'spinning.mp3']
>>> dirname = "c:\\"
>>> os.listdir(dirname)                                                          2
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin', 'docbook',
'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS', 'MSDOS.SYS', 'Music',
'NTDETECT.COM', 'ntldr', 'pagefile.sys', 'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
>>> [f for f in os.listdir(dirname) if os.path.isfile(os.path.join(dirname, f))] 3
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS',
'NTDETECT.COM', 'ntldr', 'pagefile.sys']
>>> [f for f in os.listdir(dirname) if os.path.isdir(os.path.join(dirname, f))]  4
['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
1 listdir 函数接收一个路径名,它返回那个目录的内容的一个列表。
2 listdir 同时返回文件和文件夹,并不指出哪个是文件,哪个是文件夹。
3

你可以使用列表过滤os.path 模块的 isfile 函数,从文件夹中将文件分离出来。isfile 接收一个路径名,如果路径表示一个文件,则返回 1,否则为 0。在这里,我们使用 os.path.join 来确保一个全路径名,但 isfile 对一个相对于当前工作目录的部分路径也是有效的。你可以使用 os.path.getcwd() 来得到当前的工作目录。

4 os.path 还有一个 isdir 函数,当路径表示一个目录,则返回 1,否则为 0。你可以使用它来得到一个目录下的子目录列表。

例 3.37. 在 fileinfo.py 中列出目录


def listDirectory(directory, fileExtList):                                        
    "get list of file info objects for files of particular extensions"
    fileList = [os.path.normcase(f) for f in os.listdir(directory)]               
    fileList = [os.path.join(directory, f) for f in fileList \
                if os.path.splitext(f)[1] in fileExtList]                         

这两行代码合并了迄今为止对于 os 模块我们已经学过的所有东西,接着还有一些别的。

  1. os.listdir(directory) 返回在directory 中所有文件和文件夹的一个列表。
  2. 使用 f 对列表进行遍历,我们使用 os.path.normcase(f) 根据操作系统的缺省值对大小写进行标准化处理。normcase 是一个有用的函数,用于对大小写不敏感操作系统的一个补充。这种操作系统认为 mahadeva.mp3mahadeva.MP3 是同一个文件名。例如,在Windows和Mac OS下,normcase 将把整个文件名转换为小写字母;而在UNIX兼容的系统下,它将返回未作修改的文件名。
  3. 再次用 f 对标准化后的列表进行遍历,我们使用 os.path.splitext(f)将每个文件名分割为名字和扩展名。
  4. 对每个文件,我们查看是否扩展名在我们关心的文件扩展名列表中(fileExtList,被传递给 listDirectory 函数)。
  5. 对每个我们所关心的文件,我们使用 os.path.join(directory, f) 来构造这个文件的全路径名,接着返回这个全路径名的列表。
Note
只要有可能,你应该使用在 osos.path 中的函数进行文件,目录,和路径的操作。这些模块是对平台相关模块的封装模块,所以象 os.path.split 这样的函数可以工作在UNIX,Windows,Mac OS,和Python所支持的任一种平台上。

进一步阅读