楼主: lastwinner

[参考文档] Python 研究(Dive Into Python)

[复制链接]
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
91#
 楼主| 发表于 2006-7-15 19:42 | 只看该作者
6.2.4. 写入文件
正如你所期待的, 你也能用与读取文件同样的方式写入文件。 有两种基本的文件模式:

"Append" 模式将数据追加到文件尾。
"write" 模式将覆盖文件的原有内容。
如果文件还不存在, 任意一种模式都将自动创建文件, 因此从来不需要任何复杂的逻辑 "如果 log 文件还不存在, 将创建一个新的空文件,正因为如此,你可以第一次就打开它" 。 打开文件并开始写就可以了。

例 6.7. 写入文件
>>> logfile = open('test.log', 'w')
>>> logfile.write('test succeeded')
>>> logfile.close()
>>> print file('test.log').read()   
test succeeded
>>> logfile = open('test.log', 'a')
>>> logfile.write('line 2')
>>> logfile.close()
>>> print file('test.log').read()   
test succeededline 2
  你可以大胆地开始创建任何的新文件 test.log 或覆盖现有文件, 为写入目的而打开它。 (第二个参数 "w" 的意思是为文件写入而打开。) 是的,它和想象中的一样危险。 我希望你不必关心文件以前的内容, 因为它现在已经不存在了。
  你可以使用 open 返回的文件对象的 write 方法向一个新打开的文件添加数据。
  file 是 open 的同义语。 它用一行打开文件, 读取内容, 并打印它们。
  碰巧你知道 test.log 存在 (因为你刚向它写完了数据), 所以你可以打开它并向其追加数据。 ("a" 参数的意思是为追加目的打开文件。) 实际上即使文件不存在你也可以这样做, 因为以追加方式打开一文件时, 如果需要的话会创建文件。 但是追加操作 从不 损坏文件的现有内容。
  正如你所看到的, 原来的行和你以追加方式写入的第二行现在都在 test.log 中了。 同时注意回车符并没包含进来。 因为两次写入文件时都没有明确地写入回车符, 所以文件中没有包含回车符。 你可以用 "\n" 写入回车符。 因为你没做这项工作, 所以你写到文件的所有内容都将显示在同一行上。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
92#
 楼主| 发表于 2006-7-15 19:42 | 只看该作者
进一步阅读

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
93#
 楼主| 发表于 2006-7-15 19:42 | 只看该作者
6.3. for 循环
与其它大多数语言一样,Python 也拥有 for 循环。你到现在还未曾看到它们的唯一原因就是,Python 在其它太多的方面表现出色,通常你不需要它们。

其它大多数语言没有象 Python 一样的强大的 list 数据类型,所以你需要亲自做很多事情,指定开始,结束和步长,来定义一定范围的整数或字符或其它可重复的实体。但是在 Python 中,for 循环简单地在一个列表上循环,与 list 解析 的工作方式相同。

例 6.8. for 循环介绍
>>> li = ['a', 'b', 'e']
>>> for s in li:         
...     print s         
a
b
e
>>> print "\n".join(li)  
a
b
e  for 循环的语法同 list 解析 相似。li 是一个 list,而 s 将从第一个元素开始依次接收每个元素的值。
  象 if 语句或其它任意 缩进块,for 循环可以在它里面有任意条数的代码行。
  这就是为什么你以前没看到过 for 循环的原因:至今我们都不需要它。太令人吃惊了,当你想要的只是一个 join 或是 list 解析时,而用其它语言常常需要使用 for 循环。

要做一个 “通常的” (Visual Basic 标准的) 计数 for 循环也非常简单。

例 6.9. 简单计数
>>> for i in range(5):            
...     print i
0
1
2
3
4
>>> li = ['a', 'b', 'c', 'd', 'e']
>>> for i in range(len(li)):      
...     print li
a
b
c
d
e
  正如你在 例 3.20 “连续值赋值” 所看到的,range 生成一个整数的 list, 通过它来控制循环。 我知道它看上去有些奇怪, 但是它对计数循环偶尔 (我只是说 偶尔) 会有用 。
  我们从来没这么用过。 这是 Visual Basic 的思维风格。摆脱它吧。 正确遍历 list 的方法是前面的例子所展示的。

for 循环不仅仅用于简单计数。 它们可以遍历任何类型的东西。 下面的例子是一个用 for 循环遍历 dictionary 的例子。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
94#
 楼主| 发表于 2006-7-15 19:42 | 只看该作者
例 6.10. 遍历 dictionary
>>> import os
>>> for k, v in os.environ.items():      
...     print "%s=%s" % (k, v)
USERPROFILE=C:\Documents and Settings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim

[...略...]
>>> print "\n".join(["%s=%s" % (k, v)
...     for k, v in os.environ.items()])
USERPROFILE=C:\Documents and Settings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim

[...略...]  os.environ 是在你的系统上所定义的环境变量的 dictionary。在 Windows 下,这些变量是可以从 MS-DOS 访问的用户和系统变量。在 UNIX 下,它们是在你的 shell 启动脚本中所 export(输出)的变量。在 Mac OS 中,没有环境变量的概念,所以这个 dictionary 为空。
  os.environ.items() 返回一个 tuple 的 list:[(key1, value1), (key2, value2), ...]。 for 循环对这个 list 进行遍历。第一轮,它将 key1 赋给 k ,value1 赋给 v,所以 k = USERPROFILE,v = C:\Documents and Settings\mpilgrim。第二轮,k 得到第二个键字,OS,v 得到相应的值,Windows_NT。
  使用 多变量赋值 和 list 解析,你可以使用单行语句来替换整个 for 循环。在实际的编码中是否这样做只是个人风格问题;我喜欢它是因为,可以使得将一个 dictionary 映射到一个 list,然后将 list 合并成一个字符串,这一过程显得很清晰。其它的程序员宁愿将其写成一个 for 循环。请注意在两种情况下输出是一样的,然而这一版本稍微快一些,因为它只有一条 print 语句而不是许多。

现在我们来看看在 第 5 章 介绍的样例程序 fileinfo.py 中 MP3FileInfo 的 for 循环 。

例 6.11. MP3FileInfo 中的 for 循环
    tagDataMap = {"title"   : (  3,  33, stripnulls),
                  "artist"  : ( 33,  63, stripnulls),
                  "album"   : ( 63,  93, stripnulls),
                  "year"    : ( 93,  97, stripnulls),
                  "comment" : ( 97, 126, stripnulls),
                  "genre"   : (127, 128, ord)}                              
    .
    .
    .
            if tagdata[:3] == "TAG":
                for tag, (start, end, parseFunc) in self.tagDataMap.items():
                    self[tag] = parseFunc(tagdata[start:end])                  tagDataMap 是一个 类属性 ,它定义了我们正在一个 MP3 文件中搜索的标记。标记存储为定长字段,一旦我们读出文件最后 128 个字节,第 3 到 32 字节总是歌曲的名字,33-62 总是歌手的名字,63-92 为专辑的名字,等等。请注意 tagDataMap 是一个 tuple 的 dictionary,每个 tuple 包含两个整数和一个函数引用。
  这个看上去复杂一些,但其实并非如此。这个 for 变量结构与 items 所返回的 list 的元素的结构相匹配。记住,items 返回一个形如 (key, value) 的 tuple 的 list。list 第一个元素是 ("title", (3, 33, <function stripnulls>),所以循环的第一轮,tag 为 "title",start 为 3,end 为 33,parseFunc 为函数 stripnulls。
  现在我们已经从一个单个的 MP3 标记中提取出了所有的参数,将标记数据保存起来挺容易。我们从 start 到 end 对 tagdata 进行 分片,从而得到这个标记的实际数据,调用 parseFunc 对数据进行后续的处理,接着将 parseFunc 作为值赋值给伪字典 self 中的键字 tag。在遍历完 tagDataMap 中所有元素之后, self 拥有了所有标记的值, 你知道看上去是什么样。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
95#
 楼主| 发表于 2006-7-15 19:43 | 只看该作者
6.4. 使用 sys.modules
与其它任何 Python 的东西一样, 模块也是对象。 一旦导入,总可以用全局 dictionary sys.modules 来得到一个模块的引用。

例 6.12. sys.modules 介绍
>>> import sys                          
>>> print '\n'.join(sys.modules.keys())
win32api
os.path
os
exceptions
__main__
ntpath
nt
sys
__builtin__
site
signal
UserDict
stat  这个 sys 模块包含了系统级的信息,象正在运行的 Python 的版本 (sys.version 或 sys.version_info),和系统级选项,象最大允许递归的深度 (sys.getrecursionlimit() 和 sys.setrecursionlimit())。
  sys.modules 是一个字典,它包含了从 Python 开始运行起,被导入的所有模块。键字就是模块名,键值就是模块对象。请注意除了你的程序导入的模块外还有其它模块。Python 在启动时预先装入了一些模块,如果你在一个 Python IDE 环境下,sys.modules 包含了你在 IDE 中运行的所有程序所导入的所有模块。

下面的例子展示了如何使用 sys.modules。

例 6.13. 使用 sys.modules
>>> import fileinfo         
>>> print '\n'.join(sys.modules.keys())
win32api
os.path
os
fileinfo
exceptions
__main__
ntpath
nt
sys
__builtin__
site
signal
UserDict
stat
>>> fileinfo
<module 'fileinfo' from 'fileinfo.pyc'>
>>> sys.modules["fileinfo"]
<module 'fileinfo' from 'fileinfo.pyc'>  当导入新的模块,它们加入到 sys.modules 中。这就解释了为什么第二次导入相同的模块时非常的快:Python 已经在 sys.modules 中装入和缓冲了,所以第二次导入仅仅对字典做了一个查询。
  一旦给出任何以前导入过的模块名(以字符串方式),通过 sys.modules 字典,你可以得到对模块本身的一个引用。

下面的例子介绍 sys.modules dictionary 的 __module__ 属性,可以作为理解已定义类中 __module__ 属性的参考。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
96#
 楼主| 发表于 2006-7-15 19:43 | 只看该作者
例 6.14. __module__ 类属性
>>> from fileinfo import MP3FileInfo
>>> MP3FileInfo.__module__              
'fileinfo'
>>> sys.modules[MP3FileInfo.__module__]
<module 'fileinfo' from 'fileinfo.pyc'>  每个 Python 类拥有一个内置的 类属性 __module__,它定义了这个类的模块的名字。
  将它与 sys.modules 字典复合使用,你可以得到定义了某个类的模块的引用。

现在准备好了, 看看在样例程序 第 5 章 sys.modules 介绍的 fileinfo.py 中是如何使用的。 这个例子显示它的一部分代码。

例 6.15. fileinfo.py 中的 sys.modules
    def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):      
        "get file info class from filename extension"                             
        subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]        
        return hasattr(module, subclass) and getattr(module, subclass) or FileInfo   这是一个有两个参数的函数;filename 是必须的,但 module 是 可选的 并且 module 的缺省值包含了 FileInfo 类。这样看上去效率低,因为你可能认为 Python 会在每次函数调用时计算这个 sys.modules 表达式。实际上,Python 仅会对缺省表达式计算一次,是在模块导入的第一次。正如后面我们会看到的,我们永远不会用一个 module 参数来调用这个函数,所以 module 的功能是作为一个函数级别的常量。
  我们会在后面再仔细研究这一行,在我们了解了 os 模块之后。那么现在,只要相信 subclass 最终为一个类的名字就行了,象 MP3FileInfo。
  你已经了解了 getattr,它可以通过名字得到一个对象的引用。hasattr 是一个补充性的函数,用来检查是否一个对象具有一个特别的属性;在本例中,用来检查一个模块是否有一个特别的类 (然而它可以用于任何类和任何属性,就象 getattr)。用英语来说,这行代码是说, “If this module has the class named by subclass then return it, otherwise return the base class FileInfo (如果这个模块有一个名为 subclass 的类,那么返回它,否则返回基类 FileInfo)”。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
97#
 楼主| 发表于 2006-7-15 19:43 | 只看该作者

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
98#
 楼主| 发表于 2006-7-15 19:43 | 只看该作者
6.5. 与 Directory 共事
os.path 模块有几个操作文件和目录的函数。 这里, 我们看看如何操作路径名和列出一个目录的内容。

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

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

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
99#
 楼主| 发表于 2006-7-15 19:44 | 只看该作者
例 6.18. 列出目录
>>> os.listdir("c:\\music\\_singles\\"              
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> dirname = "c:\\"
>>> os.listdir(dirname)                              
['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))]
['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))]  
['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']  listdir 函数接收一个路径名,它返回那个目录的内容的一个 list。
  listdir 同时返回文件和文件夹,并不指出哪个是文件,哪个是文件夹。
  你可以使用 过滤列表 和 os.path 模块的 isfile 函数,从文件夹中将文件分离出来。isfile 接收一个路径名,如果路径表示一个文件,则返回 1,否则为 0。在这里,我们使用 os.path.join 来确保一个全路径名,但 isfile 对一个相对于当前工作目录的部分路径也是有效的。你可以使用 os.getcwd() 来得到当前的工作目录。
  os.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)]            
    fileList = [os.path.join(directory, f)
               for f in fileList
                if os.path.splitext(f)[1] in fileExtList]      os.listdir(directory) 返回在 directory 中所有文件和文件夹的一个 list。
  使用 f 对 list 进行遍历,我们使用 os.path.normcase(f) 根据操作系统的缺省值对大小写进行标准化处理。 normcase 是一个有用的函数,用于对大小写不敏感操作系统的一个补充。这种操作系统认为 mahadeva.mp3 和 mahadeva.MP3 是同一个文件名。例如,在 Windows 和 Mac OS 下,normcase 将把整个文件名转换为小写字母;而在 UNIX 兼容的系统下,它将返回未作修改的文件名。
  再次用 f 对标准化后的 list 进行遍历,我们使用 os.path.splitext(f) 将每个文件名分割为名字和扩展名。  
  对每个文件,我们查看是否扩展名在我们关心的文件扩展名 list 中 (fileExtList,被传递给 listDirectory 函数)。
  对每个我们所关心的文件,我们使用 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\\"               
['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')           
['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')         
['c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\*\\*.mp3')                  
  正如你前面看到的, os.listdir 简单的取出一个目录路径, 目录中的所有文件和子目录。
  glob 模块, 另一方面, 选取一个通配符并且返回文件的或目录的完整路径与之匹配。 这个通配符是一个目录路径加上 "*.mp3", 它将匹配所有的 .mp3 文件。 注意返回列表的每一个元素已经包含了文件的完整路径。
  如果你要查找指定目录中所有以 "s" 开头并以 ".mp3" 结尾的文件, 也可以这么做。
  现在考查这种情况: 你有一个 music 目录, 它包含几个子目录, 子目录中包含一些 .mp3 文件。 你可以用两个通配符仅仅调用 glob 一次立刻获得所有这些文件的一个 list。 一个通配符是 "*.mp3" (用于匹配 .mp3 文件), 另一个通配符是 子目录名本身, 用于匹配 c:\music 中的所有子目录。 这看上去很简单, 但他蕴含了强大的功能。

使用道具 举报

回复
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
100#
 楼主| 发表于 2006-7-15 19:44 | 只看该作者
进一步阅读

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表