6.6. 全部放在一起

再一次,所有的多米诺骨牌都放好了。我们已经看过每行代码是如何工作的了。现在往回走一步,看一下放在一起是怎么样的。

例 6.21. listDirectory


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]                          
    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 
    return [getFileInfoClass(f)(f) for f in fileList]                              
listDirectory 是整个模块主要的有趣之处。它接收一个 dictionary (在我的例子中如 c:\music\_singles\) 和一个感兴趣的文件扩展名列表 (如 ['.mp3']),接着它返回一个类实例的 list ,这些类实例的行为像 dictionary,包含了在目录中每个感兴趣文件的元数据。并且实现起来只用了几行直观的代码。
正如在前一节我们所看到的,这行代码得到一个全路径名的列表,它的元素是在 directory 中有着我们感兴趣的文件后缀 (由 fileExtList 所指定的) 的所有文件的路径名。
老学校出身的 Pascal 程序员可能对嵌套函数感到熟悉,但大部分人,当我告诉他们 Python 支持嵌套函数时,都茫然地看着我。嵌套函数,从字面理解,是定义在函数内的函数。嵌套函数 getFileInfoClass 只能在定义它的函数 listDirectory 内进行调用。正如任何其它的函数一样,不需要一个接口声明或奇怪的什么东西,只要定义函数,开始编码就行了。
既然你已经看过 os 模块了,这一行应该能理解了。它得到文件的扩展名 (os.path.splitext(filename)[1]),将其转换为大写字母 (.upper()),从圆点处进行分片 ([1:]),使用字符串格式化从其中生成一个类名。所以 c:\music\ap\mahadeva.mp3 变成 .mp3 再变成 MP3 再变成 MP3FileInfo
在生成完处理这个文件的处理类的名字之后,我们查阅在这个模块中是否存在这个处理类。如果存在,我们返回这个类,否则我们返回基类 FileInfo。这一点很重要:这个函数返回一个类。不是类的实例,而是类本身。
对每个属于我们 “感兴趣文件” 列表 (fileList)中的文件,我们用文件名 (f) 来调用 getFileInfoClass。调用 getFileInfoClass(f) 返回一个类;我们并不知道确切是哪一个类,但是我们并不关心。接着我们创建这个类 (不管它是什么) 的一个实例,传入文件名 (又是 f) 给 __init__ 方法。正如我们在本章的前面所看到的,FileInfo__init__ 方法设置了 self["name"],它将引发 __setitem__ 的调用,而 __setitem__ 在子类 (MP3FileInfo) 中被覆盖掉了,用来适当地对文件进行分析,取出文件的元数据。我们对所有感兴趣的文件进行处理,返回结果实例的一个 list。

请注意 listDirectory 完全是通用的。它事先不知道将得到哪种类型的文件,也不知道哪些定义好的类能够处理这些文件。它检查目录中要进行处理的文件,然后反观本身模块,了解定义了什么特别的处理类 (像 MP3FileInfo)。你可以对这个程序进行扩充,对其它类型的文件进行处理,只要用适合的名字定义类:HTMLFileInfo 用于 HTML 文件,时时彩计划软件公式:DOCFileInfo 用于 Word .doc 文件,等等。不需要改动函数本身, listDirectory 将会对它们都进行处理,将工作交给适当的类,接着收集结果。

时时彩黑客改单存在吗 江西大乐透官网 重庆时时彩倍投计划 重庆时时彩后三组三玩法 捷豹平台彩票代理
江西时时彩三星包组 新时时彩软件 奇妙重庆时时彩软件破解版 破解时时彩 新疆时时彩开奖直播
大龙虾时时彩软件5.0 时时彩开奖号码走势图 时时彩最佳投注方案 时时彩买奇偶怎么买 时时彩杀码99以上
杏彩时时彩平台官网 江西大乐透官网 时时彩后一平刷万能码 时时彩软件排行榜 时时彩平台怎么刷钱
山东11选5走势图表360 体彩江苏十一选五开奖结果查询☆﹤计划﹥ 甘肃快三开奖查询 内蒙古时时彩十一选五开奖结果 百家乐技巧
安徽快3助赢软件 博彩网排名 吉林快三走势图表今天 黑龙江快乐十分彩票控 体彩排列三走势图
贵州11选5开奖结果查询 加拿大极速飞艇开奖 北京十一选五前三走势图 快三走势图 北京快乐8走势图
排列3试机号 重庆时时彩代打论坛 云南十一选五开奖结果?广东11选5号码推荐?11选五选号技巧与规律?河北体彩十一选五号码 湖北快3遗漏号码 云南时时彩玩法介绍