🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 6.7. 小结 在 [第 5 章](../object_oriented_framework/index.html) 介绍的 `fileinfo.py` 程序现在应该完全理解了。 ``` """Framework for getting filetype-specific metadata. Instantiate appropriate class with filename. Returned object acts like a dictionary, with key-value pairs for each piece of metadata. import fileinfo info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3") print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()]) Or use listDirectory function to get info on all files in a directory. for info in fileinfo.listDirectory("/music/ap/", [".mp3"]): ... Framework can be extended by adding classes for particular file types, e.g. HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for parsing its files appropriately; see MP3FileInfo for example. """ import os import sys from UserDict import UserDict def stripnulls(data): "strip whitespace and nulls" return data.replace("\00", "").strip() class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" 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)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == "TAG": for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item) 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] if __name__ == "__main__": for info in listDirectory("/music/_singles/", [".mp3"]): print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) print ``` 在研究下一章之前,确保你可以无困难地完成下面的事情: * 使用 [`try...except`](index.html#fileinfo.exception "6.1. 异常处理") 来捕捉异常 * 使用 [`try...finally`](file_objects.html#fileinfo.files.incode "例 6.6. MP3FileInfo 中的文件对象") 来保护额外的资源 * 读取[文件](file_objects.html "6.2. 与文件对象共事") * 在一个 [`for` 循环](for_loops.html#fileinfo.multiassign.for.example "例 6.11. MP3FileInfo 中的 for 循环")中一次赋多个值 * 使用 [`os`](os_module.html "6.5. 与目录共事") 模块来满足你的跨平台文件操作的需要 * 通过将类看成对象并传入参数,动态地[实例化未知类型的类](all_together.html "6.6. 全部放在一起")