返回介绍

6.5. 与 Directory 共事

发布于 2019-09-14 13:30:36 字数 13728 浏览 946 评论 0 收藏 0

6.5. 与 Directory 共事

os.path 模块有几个操作文件和目录的函数。 这里, 我们看看如何操作路径名和列出一个目录的内容。

例 6.16. 构造路径名

>>> 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'
1os.path 是一个模块的引用;使用哪一个模块要看你正运行在哪种平台上。就象 getpass 通过将 getpass 设置为一个与平台相关的函数从而封装了平台之间的不同。os 通过设置 path 封装不同的相关平台模块。
2os.path 的 join 函数用一个或多个部分路径名构造成一个路径名。在这个简单的例子中,它只是将字符串进行连接。 (请注意在 Windows 下处理路径名是一个麻烦的事,因为反斜线字符必须被转义。)
3在这个几乎没有价值的例子中,在将路径名加到文件名上之前,join 将在路径名后添加额外的反斜线。当我发现这一点时我高兴极了,因为当用一种新的语言创建我自已的工具包时,addSlashIfNecessary 总是我必须要写的那些愚蠢的小函数之一。在 Python 中 不要 写这样的愚蠢的小函数,聪明的人已经为你考虑到了。
4expanduser 将对使用 ~ 来表示当前用户根目录的路径名进行扩展。在任何平台上,只要用户拥有一个根目录,它就会有效,象Windows, UNIX 和 Mac OS X, 但在 Mac OS 上无效。
5将这些技术合在一起,你可以容易地对在用户根目录下为目录和文件构造出路径名。

例 6.17. 分割路径名

>>> 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'
1split 函数对一个全路径名进行分割,返回一个包含路径和文件名的 tuple。还记得我说过你可以使用 多变量赋值 从一个函数返回多个值吗?对,split 就是这样一个函数。
2我们将 split 函数的返回值赋值给一个两个变量的 tuple。每个变量接收到返回 tuple 相对应的元素值。
3第一个变量,filepath,接收到从 split 返回 tuple 的第一个元素的值,文件路径。
4第二个变量,filename,接收到从 split 返回 tuple 的第二个元素的值,文件名。
5os.path 也包含了一个 splitext 函数,可以用来对文件名进行分割,并且返回一个包含了文件名和文件扩展名的 tuple。我们使用相同的技术来将它们赋值给独立的变量。

例 6.18. 列出目录

>>> 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']
1listdir 函数接收一个路径名,它返回那个目录的内容的一个 list。
2listdir 同时返回文件和文件夹,并不指出哪个是文件,哪个是文件夹。
3你可以使用 过滤列表 和 os.path 模块的 isfile 函数,从文件夹中将文件分离出来。isfile 接收一个路径名,如果路径表示一个文件,则返回 1,否则为 0。在这里,我们使用 os.path.join 来确保一个全路径名,但 isfile 对一个相对于当前工作目录的部分路径也是有效的。你可以使用 os.getcwd() 来得到当前的工作目录。
4os.path 还有一个 isdir 函数,当路径表示一个目录,则返回 1,否则为 0。你可以使用它来得到一个目录下的子目录列表。

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

还有一种获得 directory 内容的方法。 它非常强大, 它使用了一些你在命令行上工作时可能已经熟悉的通配符。

例 6.20. Listing Directories with glob

>>> os.listdir("c:\\music\\_singles\\")               1
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> import glob
>>> glob.glob('c:\\music\\_singles\\*.mp3')           2
['c:\\music\\_singles\\a_time_long_forgotten_con.mp3',
'c:\\music\\_singles\\hellraiser.mp3',
'c:\\music\\_singles\\kairo.mp3',
'c:\\music\\_singles\\long_way_home1.mp3',
'c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\_singles\\s*.mp3')          3
['c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\*\\*.mp3')                  4
1正如你前面看到的, os.listdir 简单的取出一个目录路径, 目录中的所有文件和子目录。
2glob 模块, 另一方面, 选取一个通配符并且返回文件的或目录的完整路径与之匹配。 这个通配符是一个目录路径加上 "*.mp3", 它将匹配所有的 .mp3 文件。 注意返回列表的每一个元素已经包含了文件的完整路径。
3如果你要查找指定目录中所有以 "s" 开头并以 ".mp3" 结尾的文件, 也可以这么做。
4现在考查这种情况: 你有一个 music 目录, 它包含几个子目录, 子目录中包含一些 .mp3 文件。 你可以用两个通配符仅仅调用 glob 一次立刻获得所有这些文件的一个 list。 一个通配符是 "*.mp3" (用于匹配 .mp3 文件), 另一个通配符是 子目录名本身, 用于匹配 c:\music 中的所有子目录。 这看上去很简单, 但他蕴含了强大的功能。

进一步阅读

  • Python Knowledge Base 回答了 关于 os 模块的问题。
  • Python Library Reference 提供了 os 模块和 os.path 模块的文档。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文