无聊之人--除了技术,还是技术,你懂得
分类: Python/Ruby
2011-08-13 18:49:39
6.5. Working with Directories
使用目录
The os.path module has several functions for manipulating files and directories. Here, we're looking at handling pathnames and listing the contents of a directory.
Os.path模块包含哟好几个函数来操纵文件和目录。在此我们只看看处理处理文件路径以及显示列表的内容。
Example 6.16. Constructing Pathnames
例6.16 构建路径
os.path is a reference to a module
-- which module depends on your platform. Just as getpass encapsulates differences between
platforms by setting getpass to a platform-specific
function, os encapsulates differences between platforms by
setting path to a platform-specific module. Os.path是一个模块引用—该引用依赖于你的平台。正如getpass通过设置针对特定平台的getpass函数来封装不同的差异,os模块通过封装针对特定平台的模块来区别不同的差异。 The join function
of os.path constructs a pathname out of one or more partial
pathnames. In this case, it simply concatenates strings. (Note that dealing
with pathnames on Windows is annoying because the backslash character must be
escaped.) Os.path的join函数通过使用一个或是几个特殊路径来构建一个新的路径。在本例中,它只是简单的对字符串进行连接。(请注意在windows上处理路径是很烦人的,这是因为反斜杠(\)必须进行转义(\\)。 In this slightly less trivial
case, join will add an extra backslash to the pathname before
joining it to the filename. I was overjoyed when I discovered this,
sinceaddSlashIfNecessary is one of the stupid little functions I always
need to write when building up my toolbox in a new language. Do not write
this stupid little function inPython; smart people have already taken care of
it for you. 在这个微不足道的例子中,在将pathname与文件名进行连接之前,join 会增加一个额外的反斜杠。当我发现这点的时候,我差点兴奋过度。每当我在我的新语言中构建工具箱时,我经常使用addSlashIfNecessary,因为它是一个十分笨拙的小函数。不要在Python写这种小的笨拙函数:聪明的人都会替你好好保重它。 expanduser will expand a pathname
that uses ~ to represent the current user's home directory. This
works on any platform where users have a home directory, like
Windows, UNIX, and Mac OS X; it has no effect
on Mac OS. Expanduser将会扩展路径,它使用~来代表当前的用户目录。如果一个用户有家目录,这个函数对任何平台都是适用,比如windows,UNIX,和Mac
OS X;在Mac OS该函数没有任何效果。 Combining these techniques, you can
easily construct pathnames for directories and files under the user's home
directory. 综合这些技术,你就能轻松的在用户的家目录(home directory)下为目录和文件构建一个路径
Example 6.17. Splitting Pathnames
例6.17 路径分隔
The split function splits a
full pathname and returns a tuple containing the path and filename. Remember
when I said you could use multi-variable assignment to return multiple values from a
function? Well, split is such a function. Split函数将一个完整的路径进行分隔,然后返回一个包含了路径和文件的不变数组。你还记的当我说你可以使用一个函数,返回不变数组来进行多个变量连续赋值么?哦,split就是一个这样的函数。 You assign the return value of
the split function into a tuple of two variables. Each variable
receives the value of the corresponding element of the returned tuple. 你将split函数的返回值赋值给包含有两个变量的不变数组。每一个变量都会获得返回不变数组相对应的元素值。 The first variable, filepath,
receives the value of the first element of the tuple returned
from split, the file path 第一个变量,filepath,获得了split返回的不变数组的第一个元素的值,即文件的路径。 The second variable, filename,
receives the value of the second element of the tuple returned
from split, the filename. 第二个变量,filename,被赋值为split函数返回的不变数组的第二个元素的值,文件名字。 os.path also contains a
function splitext, which splits a filename and returns a tuple
containing the filename and the file extension. You use the same technique to
assign each of them to separate variables. Os.path 同样包含了一个函数,splittext,该函数对一个文件名字进行分隔,然后返回一个不变数组,该数组包含了文件名字和文件扩展名。你使用同样的方法来对各自的变量进行赋值。
Example 6.18. Listing Directories
例6.18 显示目录
The listdir function takes a
pathname and returns a list of the contents of the directory. Listdir函数接受一个参数,然后返回包含了目录内容的列表。 listdir returns both files and
folders, with no indication of which is which. Listdir同时返回了文件和目录,但是没有说明这二者之间的包含关系。 You can use list
filtering and the isfile function of the os.path module
to separate the files from the folders. isfile takes a pathname and
returns 1 if the path represents a file, and 0 otherwise. Here you're
using os.path.join to ensure a full pathname,
but isfile also works with a partial path, relative to the current
working directory. You can use os.getcwd() to get the current
working directory. 你可以使用链表过滤和os.path模块的isfile函数来从目录中区分文件。Iffile接受一个函数,然后返回1,如果该路径代表了一个文件,其它的则返回0.在此你正在使用os.path.join以确保一个全文件名,但是iffile对相对路径同样适用,它同当前工作目录相关联。你可以使用os.getcwd来获取当前的工作目录。 os.path also has
a isdir function which returns 1 if the path represents a
directory, and 0 otherwise. You can use this to get a list of the
subdirectories within a directory. Os.path同样含有一个isdir函数。该函数返回1,如果路径代表了一个目录,其它的则返回0.你可以使用这个函数来显示一个目录内的子目录。
Example 6.19. Listing Directories in fileinfo.py
例6.19 在文件fileinfo.py中显示目录
os.listdir(directory) returns a
list of all the files and folders in directory. Os.listdir(directory)返回一个目录中所有的文件和文件夹。 Iterating through the list with f,
you use os.path.normcase(f) to normalize the case according to
operating system defaults. normcase is a useful little function
that compensates for case-insensitive operating systems that think
that mahadeva.mp3 and mahadeva.MP3 are the same file. For
instance, on Windows and Mac OS, normcase will convert
the entire filename to lowercase; on UNIX-compatible systems, it will
return the filename unchanged. 使用变量f来对列表进行迭代。根据操作系统的默认值,你可以使用os.path.normcase(f)来规范这种情况。Normcas是一个有用的小函数,它是对大小写系统不敏感的系统(mahadeva.mp3&mahaeva.MP3是同一样文件)的一种补充。 Iterating through the normalized list
with f again, you use os.path.splitext(f) to split each
filename into name and extension. 在此使用变量f,对规范化过的列表在此进行迭代,你使用os.path.splittext(f)来将每一个文件名字分隔成文件名字和和它的扩展名。 For each file, you see if the extension
is in the list of file extensions you care about (fileExtList, which was
passed to the listDirectory function). 对每一个文件,,你可以测试其文件扩展名是否在你所关心的文件扩展名列表(fileExtList,它将传递给listDirectory函数)中。 For each file you care about, you
use os.path.join(directory, f) to construct the full pathname of
the file, and return a list of the full pathnames. 对于你所关心的每一个文件,你使用os.path.join(direcory,f)来构建一个完全的文件路径,返回一个绝对路径的列表。 Whenever possible, you should use the
functions in os and os.path for file, directory, and path
manipulations. These modules are wrappers for platform-specific modules, so
functions like os.path.split work on UNIX,
Windows, Mac OS, and any other platform supported by Python. 一旦可能,对于文件,目录以及路径的操作,你就应该使用os,os.path模块中的函数。这些模块都是特定平台的包装类,因此如os.path.split这样Python所支持的的函数在UNIX,Windows,Mac
OS,以及任何其它的平台都能工作。
There is one other way to get the contents of a directory. It's very powerful, and it uses the sort of wildcards that you may already be familiar with from working on the command line.
还有另外一种可以获取目录内容的方法。它也是非常强大的。它可以使用在通配符类型,这些是你在命令行工作时都非常熟悉的。
Example 6.20. Listing Directories with glob
例6.20 使用glob来显示列表
As you saw
earlier, os.listdir simply takes a directory path and lists all
files and directories in that directory. 正如你先前所看到的,os.listdir函数只是简单的接受一个目录路径作为参数,然后显示该目录下所有的文件和子目录。 The glob module, on the other
hand, takes a wildcard and returns the full path of all files and directories
matching the wildcard. Here the wildcard is a directory path plus
"*.mp3", which will match all .mp3 files. Note that each
element of the returned list already includes the full path of the file. Glob模块,从另一个方面,接受一个同个通配符然后返回所有能匹配该通配符赋的所有文件和子目录的全路径。这里通配符是一个路径外加”*.mp3”,该通配符会匹配所有的.mp3文件。注意:返回列表的每一个元素都包含了文件的全路径。 If you want to find all the files in a
specific directory that start with "s" and end with
".mp3", you can do that too. 如果你想在特定的目录中查找以字符”s”开始并以”.mp3”结束的文件,你也可以这样做。 Now consider this scenario: you have
a music directory, with several subdirectories within it,
with .mp3 files within each subdirectory. You can get a list of all
of those with a single call to glob, by using two wildcards at once. One
wildcard is the "*.mp3" (to match .mp3 files),
and one wildcard is within the directory path itself, to match
any subdirectory within c:\music. That's a crazy amount of power packed
into one deceptively simple-looking function! 现在考虑这样的场景:你有一个音乐目录,该目录包含几个子目录,每一个子目录都含有.mp3文件。通过一次使用两个通配符,使用一个简单的对glob调用就能获得所有这些文件所组成的列表。一个通配符是“.mp3”(为了匹配.mp3),另一个通配符是包含目录路径本身内来匹配任何子目录c:\\。这是看起来让人疯狂的能力:将所有的功能都打包到一个看起来让人产生怀疑的函数中。