返回介绍

6.6. 全部放在一起

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

6.6. 全部放在一起

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

例 6.21. listDirectory

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

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

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

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

发布评论

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